Android 使用异步任务强制关闭
当客户端向服务器发送请求时,我想显示一个progressdialog..请求应该在后台完成..但是当我使用AsyncTask时,我得到了一个强制关闭..请帮助..谢谢Android 使用异步任务强制关闭,android,Android,当客户端向服务器发送请求时,我想显示一个progressdialog..请求应该在后台完成..但是当我使用AsyncTask时,我得到了一个强制关闭..请帮助..谢谢 package com.example.client; import java.io.DataInputStream; import java.io.DataOutputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.n
package com.example.client;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
public static ProgressDialog Dialog;
String s1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// sendreq();
new SendUserTask().execute();
}
});
}
public String sendreq() {
try {
// TODO Auto-generated method stub
SocketAddress sockaddr = new InetSocketAddress("192.168.7.116",
9011);
Socket serversocket = new Socket();
serversocket.connect(sockaddr, 10000);
serversocket.setSoTimeout(10000);
DataOutputStream out = new DataOutputStream(
serversocket.getOutputStream());
out.flush();
DataInputStream in = new DataInputStream(
serversocket.getInputStream());
out.flush();
String msg = "";
msg = "hi";
out.writeBytes(msg);
out.flush();
byte[] message = new byte[100];
in.read(message);
s1 = new String(message);
Toast.makeText(getApplicationContext(), s1, Toast.LENGTH_LONG)
.show();
((TextView) findViewById(R.id.textView1)).setText(s1);
in.close();
out.close();
serversocket.close();
} catch (Exception e) {
Toast.makeText(getApplicationContext(), String.valueOf(e),
Toast.LENGTH_LONG).show();
}
return null;
}
private class SendUserTask extends AsyncTask<Void, Void, String> {
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
Dialog = ProgressDialog.show(MainActivity.this, "",
"Logging In....", true);
super.onPreExecute();
}
protected void onPostExecute(String s) {
if (Dialog.isShowing())
Dialog.dismiss();
}
@Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
try {
return sendreq();
} catch (Exception e) {
Toast.makeText(getApplicationContext(), String.valueOf(e),
Toast.LENGTH_SHORT).show();
}
return null;
}
}
}
package com.example.client;
导入java.io.DataInputStream;
导入java.io.DataOutputStream;
导入java.net.InetSocketAddress;
导入java.net.Socket;
导入java.net.SocketAddress;
导入android.os.AsyncTask;
导入android.os.Bundle;
导入android.app.Activity;
导入android.app.ProgressDialog;
导入android.content.Intent;
导入android.view.Menu;
导入android.view.view;
导入android.view.view.OnClickListener;
导入android.widget.TextView;
导入android.widget.Toast;
公共类MainActivity扩展了活动{
公共静态进程对话框;
字符串s1;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button1).setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
//sendreq();
新建SendUserTask().execute();
}
});
}
公共字符串sendreq(){
试一试{
//TODO自动生成的方法存根
SocketAddress sockaddr=新的InetSocketAddress(“192.168.7.116”,
9011);
套接字服务器套接字=新套接字();
serversocket.connect(sockaddr,10000);
serversocket.setSoTimeout(10000);
DataOutputStream out=新的DataOutputStream(
serversocket.getOutputStream());
out.flush();
DataInputStream in=新的DataInputStream(
serversocket.getInputStream());
out.flush();
字符串msg=“”;
msg=“你好”;
out.writeBytes(msg);
out.flush();
字节[]消息=新字节[100];
阅读(信息);
s1=新字符串(消息);
Toast.makeText(getApplicationContext(),s1,Toast.LENGTH\u LONG)
.show();
((TextView)findViewById(R.id.textView1)).setText(s1);
in.close();
out.close();
serversocket.close();
}捕获(例外e){
Toast.makeText(getApplicationContext(),String.valueOf(e),
Toast.LENGTH_LONG).show();
}
返回null;
}
私有类SendUserTask扩展了AsyncTask{
@凌驾
受保护的void onPreExecute(){
//TODO自动生成的方法存根
Dialog=ProgressDialog.show(MainActivity.this,“,
“登录…”,正确);
super.onPreExecute();
}
受保护的void onPostExecute(字符串s){
if(Dialog.isShowing())
Dialog.dismise();
}
@凌驾
受保护字符串doInBackground(无效…参数){
//TODO自动生成的方法存根
试一试{
返回sendreq();
}捕获(例外e){
Toast.makeText(getApplicationContext(),String.valueOf(e),
吐司。长度(短)。show();
}
返回null;
}
}
}
此((TextView)findViewById(R.id.textView1)).setText(s1)代码>从后台线程执行。您无法访问UI线程之外的UI元素
您需要将该部分移动到onProgressUpdate或onPostExecute,或者以runOnUiThread Runnable运行它。doInBackgorund()
是一个非UI线程,您无法访问其中的UI元素。doInBackground()中的代码运行在单独的非ui线程上,该线程无权访问布局中定义的ui元素。此外,由于您是通过意图调用另一个活动,因此您应该始终记住,活动在UI线程上运行,因此您不应该从非UI线程内部启动另一个活动
因此,删除从doInBackground()内部访问UI元素的代码“((TextView)findViewById(R.id.textView1)).setText(s1);
”并将其放入onPostExecute()
,这是一个UI线程,在doInBackground()之后调用完成后台处理。确定。。。。在谷歌搜索了很多之后,我终于明白,你不能将UI元素从主线程访问到一个新的非UI线程中…因此你不能在dobackground mtd中,甚至在dobackground调用的任何其他mts中使用诸如textview或getApplicationContext mtd tht v之类的元素…这也适用于新线程()使用runnable..感谢njzk2的帮助:)我不认为这是问题所在…因为使用AsyncTask调用mtd sendreq()不是问题所在…如果我直接通过onClick(我已经评论过的一个)调用它,它工作得很好…@user1729085是的,这就是他的观点。当从UI线程调用sendreq()
中操纵UI的部分时,它们工作正常。当从AsyncTask
中的后台线程调用它们时,它们将失败。因此,正如@njzk2所说,您需要在可以访问UI.ya的方法之一中执行UI操作。您是对的……我必须从sendreq()中删除settext和toast……并将其放在postexc中……现在工作正常……但这是否意味着我无法从UI线程访问任何元素?或者有没有办法做到这一点???对不起,我是说从非UI线程…有没有办法从doInBackground mtd访问UI元素???不,我认为你做不到。无法从后台线程访问UI元素。但是,您可以在任务执行时使用onProgressUpdate()访问UI。runOnUiThread Runnable
是另一个选项,但我更喜欢usi