我想在客户端向服务器发送请求时显示progressdialog ..请求应该在后台完成...但是当我使用AsyncTask时,我会收到一个强制关闭..请帮助..谢谢你< / p>
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;
}
}
}
答案 0 :(得分:3)
此((TextView) findViewById(R.id.textView1)).setText(s1);
从后台线程执行。您无法访问UI线程之外的UI元素。
您需要将该部分移动到onProgressUpdate或onPostExecute,或者在runOnUiThread Runnable中运行它。
答案 1 :(得分:0)
doInBackgorund()
是非UI线程,您无法访问其中的UI元素。 doInBackground()中的代码在一个单独的非ui线程上运行,该线程无法访问布局中定义的UI元素。此外,由于您通过意图调用另一个Activity,因此您应该始终牢记一个Activity在UI线程上运行,因此您永远不应该从非ui线程中启动另一个Activity。
因此,请删除代码“ ((TextView) findViewById(R.id.textView1)).setText(s1);
”,从doInBackground()内部访问UI元素,然后将其放入 onPostExecute()
中,这是一个UI线程,在doInBackground()完成后台处理后调用。
答案 2 :(得分:0)
Ok ....经过google搜索后我终于明白你无法从主线程中访问UI元素到一个新的非UI线程....所以你不能使用像textview这样的元素甚至是getApplicationContext mtd tht v在dobackground mtd中使用toast,甚至在dobackground正在调用的任何其他mts中使用....这也适用于使用runnable的新Thread()。感谢你njzk2的帮助:)