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

正如 Todd Sjolander 在此线程中所说...

多线程模型在 2.3.5 和 4.0.4 之间发生了变化。AsyncTask 现在默认让应用程序中的所有子类使用同一个线程(即一次只能运行一个 AsyncTask!)。它在这里解释:

首次引入时,AsyncTask 在单个后台线程上串行执行。从 DONUT 开始,这被更改为允许多个任务并行运行的线程池。从 HONEYCOMB 开始,任务在单个线程上执行,以避免并行执行导致的常见应用程序错误。

如果你真的想要并行执行,你可以使用 THREAD_POOL_EXECUTOR 调用 executeOnExecutor(java.util.concurrent.Executor, Object[])。

考虑到这一点,可能是另一个 AsyncTask 正在您的应用程序中运行,从而阻止该任务启动。这可以解释为什么它在您的 2.3.5 设备上运行良好,但在您的 4.0.4 平板电脑上运行良好。

于 2013-03-25T11:20:36.333 回答