繁体   English   中英

Android应用程序和AsyncTask行为异常

[英]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框架中调用onCreateonPause ,事件处理程序, onPostExecuteonPreExecute等的代码)。 如果不返回事件循环,则永远不会进入绘图代码,也不会显示进度对话框。 如果要显示对话框,则需要重新设计应用程序以实际异步使用任务。 旁注-如果您在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM