1

我将 AsyncTask 与 ProgressDialog 结合使用。查看我的代码,我在 onPostExecute 中有问题。如果任务是第一次运行,它会在handleMessage 中获得progressDialog 的空指针异常,但直接调用dismiss() 会起作用。当我在达到 onPostExecute 之前转动手机时,progressDialog.dismiss() 不起作用。为什么处理程序并不总是有效?

public class UpdateTask extends AsyncTask<Void, Void, Void> {
    private ProgressDialog progressDialog;
    private Handler handler;

public UpdateTask(Act activity) {

        progressDialog = ProgressDialog.show(Activity.this, "Wait",
                "Wait");
        progressDialog.dismiss();

        handler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                //run on UI Thread
                switch( msg.what ){
                    case MSG:                       
                        progressDialog.show();
                        break;
                    case DETACH:
                        progressDialog.dismiss();
                        break;  
                }
            }
        }; 

    }


    void detach() {
          activity=null;
                  //problematic
          //progressDialog.dismiss();
          //handler.sendEmptyMessage(DETACH);
        }




    @Override
    protected Void doInBackground(Void... params) {
        handler.sendEmptyMessage(MSG);;
        return null;
    }

    protected void onPostExecute(Void result)    {  
        if (activity==null) {
            Log.w("RotationAsync", "onPostExecute() skipped -- no activity");
          }
          else {
              //problematic
              //                  progressDialog.dismiss();
              handler.sendEmptyMessage(MSG);
                progressDialog = null;
          }
    }

};
4

2 回答 2

4

为什么需要 AsyncTask 中的 Handler?如果您想使用 Handler 从 AsyncTask 控制进度对话是正确的方法,但是,每次启动新的 UpdateTask 时都会创建和销毁当前的 Handler。如果您在 AsyncTask 之外定义处理程序,则类似于:

private Handler handler = new Handler(new Handler.Callback() {
    @Override
public boolean handleMessage(Message msg) {

    switch( msg.what ){
                case MSG:                       
                    progressDialog.show();
                    break;
                case DETACH:
                    progressDialog.dismiss();
                    break;  
            }

    return false;
}
});

现在您可以从任何后台线程安全地调用 handler.sendEmptyMessage(what),progressDialog 将仅在 UI 线程上更新。不是一个完整的修复程序,我不知道您为 DETACH 和 MSG 定义了哪些 int 值。但希望它会有所帮助。这是我用来从后台任务更新任何 UI 元素的方法。只需多阅读有关 AsyncTask 和更新 UI 元素的内容。

于 2012-07-30T03:14:20.337 回答
2

请参阅https://stackoverflow.com/a/4538370/719212
应该阅读onPreExecute()Android 文档中的相关信息。

于 2012-07-30T02:57:50.023 回答