1

ProgressDialog と組み合わせて AsyncTask を使用します。私のコードを参照してください。onPostExecute に問題があります。タスクが初めて実行されている場合、handleMessage の progressDialog に対して Null Poiter Exception が発生しますが、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 を参照してください。Androidのドキュメントを
お読みください。onPreExecute()

于 2012-07-30T02:57:50.023 に答える