[英]Android application and AsyncTask not behaving as expected
我有一个Android应用程序,它使用单独的类与服务器进行通信。 效果很好,但是当我按下应用程序上的按钮(它将消息发送到服务器)时,该按钮变为灰色,并且一切都挂起,直到收到响应为止。 我宁愿让应用程序显示一个ProgressDialog,以便用户可以看到确实正在发生的事情(而不仅仅是认为它已冻结)。
我尝试使用AsyncTask进行此操作,但是由于某种原因,它不起作用。
这是我用来与服务器通信的类:
public class ServerConnection extends AsyncTask<String, Void, String> {
private Context context;
private ProgressDialog dialog;
public ServerConnection(Context ctx){
context = ctx;
dialog = new ProgressDialog(context);
dialog.setTitle("Waiting...");
dialog.setMessage("...on the world to change.");
}
@Override
protected void onPreExecute() {
dialog.show();
}
@Override
protected void onPostExecute(String unused) {
dialog.dismiss();
}
protected String doInBackground(String... msg) {
String response = null;
try{
/**
*
* Connects to server, sends message to server, waits for and receives a reponse from server
*
**/
} catch(Exception e) {
e.printStackTrace();
}
return response;
}
}
这就是我的使用方式(请注意,这些行将通过Activity中的某些方法调用):
ServerConnection conn = new ServerConnection(this);
String response = null;
try {
response = conn.execute("ThisIsAMessageToTheServer").get();
} catch (Exception e){e.printStackTrace();}
当我单击一个按钮时,将执行一小段代码,并在几秒钟后从服务器收到响应。 因此,只要与服务器进行通信并获得正确的响应,代码就可以正常工作。 唯一的问题是,从不显示ProgressDialog。
我环顾了Google,碰到的每个示例似乎都可以像这样完全正常工作,因此我不确定是什么引起了问题。
我同意Golu的回答 。 AsyncTask
,我建议您仅在activity
创建AsyncTask
。 这样就可以仅基于onPostExecute()
获得的响应来执行所有与UI相关的操作。
但是,如果您希望继续使用现在拥有的结构,请创建一个提供回调方法的接口。 将您的活动设置为侦听器,并在活动中实现该方法。
由于在doInBackground中获得的响应将传递给asynctask的onPostExecute()。 在执行后,您可以使用接口使用回调方法将结果发送回您的活动。
//创建如下界面:
public interface OnResponseReceivedListener{
public void onResponseReceived(String response);
}
//修改您的活动代码,如下所示
public yourActivity extends Activity implements OnResponseReceivedListener {
ServerConnection conn = new ServerConnection(this);
conn.setResponseListener(this);
public void onResponseReceived(String response){
// TODO: do your UI operations based on the response.
}
}
//如下修改AsyncTask。
public class ServerConnection extends AsyncTask<String, Void, String> {
OnResponseReceivedListener mListener;
public void setResponseListener(OnResponseReceivedListener listener){
mListener = listener;
}
// Your rest of the code
@Override
protected void onPostExecute(String unused) {
mListener.onResponseReceived(unused);
dialog.dismiss();
}
}
您的问题是您的.get()
。 .get
是一个阻止调用。 这意味着直到返回之前,您都不会返回事件循环(Android框架中调用onCreate
, onPause
,事件处理程序, onPostExecute
, onPreExecute
等的代码)。 如果不返回事件循环,则永远不会进入绘图代码,也不会显示进度对话框。 如果要显示对话框,则需要重新设计应用程序以实际异步使用任务。 旁注-如果您在UI线程上像这样调用.get()
,则整个应用程序将冻结并看上去坏了。 这就是为什么他们首先迫使人们不要在UI线程上执行网络IO。
您正在使用get方法,这就是为什么ProgressDialog
对话框不出现的原因,请删除get并重试。
因为get()
方法将阻塞您的主线程。
因此,您需要重写onPostExecute()
进行结果处理。
by use use get() in AsycTask, it will become SyancTask again.
编辑尝试此代码:
public class ServerConnection extends AsyncTask<String, Void, String> {
private Context context;
private ProgressDialog dialog;
public ServerConnection(Context ctx){
context = ctx;
}
@Override
protected void onPreExecute() {
dialog = new ProgressDialog(context);
dialog.setTitle("Waiting...");
dialog.setMessage("...on the world to change.");
dialog.show();
}
@Override
protected void onPostExecute(String unused) {
}
protected String doInBackground(String... msg) {
String response = null;
try{
/**
*
* Connects to server, sends message to server, waits for and receives a reponse from server
*
**/
} catch(Exception e) {
e.printStackTrace();
}
return response;
}
public onPostExecute(String response) {
dialog.dismiss(); // dismiss dialgo here.
// preocess your response here.
}
}
使用以下代码
@Override
protected void onPreExecute() {
dialog = ProgressDialog.show(this, "Waiting...","...on the world to change.",
true);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.