2

これが私のコードです:

new Loading.LoadTast(ctx) {

            @Override
            protected String doInBackground(Integer... params) {
                Looper.prepare();
                String msg=changePwd();
                closeProgressDialog();
                if(msg == null) {
                    SmartNgApplication.getInstance().exit();
                } else {
                    BaseHelper.showToast(ctx, msg);
                }
                Looper.loop();
                return null;
            }
        }.execute();


public abstract static class LoadTast extends AsyncTask<Integer, Integer, String> {

    private ProgressDialog progressDialog;

    private Context ctx;

    public LoadTast(Context ctx) {
        this.ctx=ctx;
    }

    protected abstract String doInBackground(Integer... params);

    public void onPreExecute() {
        super.onPreExecute();
        progressDialog=ProgressDialog.show(ctx, "", "loading...", true, false);
    }

    public void onPostExecute(String result) {
        super.onPostExecute(result);
        progressDialog.dismiss();
        BaseHelper.showToast(ctx, result);
    }
}

ボタンをクリックしてメソッドを実行します。5回クリックするとAsyncTask.onPreExecute呼び出されますが、呼び出されないdoInBackgroundため、画面にはダイアログが表示されます。

私は何かが間違っていると思いますAsyncTask THREAD_POOL_EXECUTOR

4

2 に答える 2

2
  1. doInBackgroundでUI変更メソッドを呼び出さないでください。それがonPostExecuteの目的です。doInBackgroundのUIスレッドで許可されていないことだけを実行します。

  2. doInBackgroundが呼び出されない理由を確認するには、(匿名内部クラスからの)実装をLoadTastに入れてみて、それが呼び出されるかどうかを確認してください。

  3. サブクラスの呼び出しの名前をonPostExecuteとdoInBackgroundに変更して、AsyncWrapperを実装しました。例で使用しているような匿名の内部クラスでラップされたメソッドを上書きできるはずです。

これは短いバージョンです。私の実際のコードには、ラップされたメソッドの呼び出しだけでなく、いくつかの一般的な例外処理が含まれています。

public abstract class AsyncTaskWrapper<Params, Progress, Result> 
  extends AsyncTask<Params, Progress, Result> {

  @Override
  final protected Result doInBackground(Params... params) {
    return wrappedDoInBackground(params);
  }

  protected abstract Result wrappedDoInBackground(Params... params);

  protected abstract void wrappedOnPostExecute(Result result);

  final protected void onPostExecute(Result result) {

    wrappedOnPostExecute(result);
  }

}
于 2012-06-20T05:59:55.340 に答える
1

ToddSjolanderがこのスレッドで言ったように...

マルチスレッドモデルが2.3.5と4.0.4の間で変更されました。AsyncTaskは、デフォルトで、同じスレッドを使用するアプリケーション内のすべてのサブクラスを持つようになりました(つまり、一度に実行できるAsyncTaskは1つだけです!)。ここで説明されています:

最初に導入されたとき、AsyncTasksは単一のバックグラウンドスレッドでシリアルに実行されていました。DONUT以降、これはスレッドのプールに変更され、複数のタスクを並行して操作できるようになりました。HONEYCOMB以降、並列実行によって引き起こされる一般的なアプリケーションエラーを回避するために、タスクは単一スレッドで実行されます。

本当に並列実行が必要な場合は、THREAD_POOL_EXECUTORを使用してexecuteOnExecutor(java.util.concurrent.Executor、Object [])を呼び出すことができます。

そのことを念頭に置いて、別のAsyncTaskがアプリで実行されている可能性があります。これにより、このタスクが開始されなくなります。これは、2.3.5デバイスでは正常に動作するが、4.0.4タブレットでは正常に動作しない理由を説明します。

于 2013-03-25T11:20:36.333 に答える