Sunxc
Sunxc

Reputation: 35

AsyncTask not call doInBackground methods

Here is my code:

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);
    }
}

Click the button to run the method. Clicking it 5 times AsyncTask.onPreExecute is called but not call doInBackground so the screen still show a dialog.

I think have something wrong for AsyncTask THREAD_POOL_EXECUTOR

Upvotes: 2

Views: 6103

Answers (2)

Oakshiro
Oakshiro

Reputation: 11

As Todd Sjolander said in this thread ...

The multi-threading model changed between 2.3.5 and 4.0.4. AsyncTask now defaults to having all subclasses in an application using the same thread (i.e. only one AsyncTask can run at a time!). It's explained here:

When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.

If you truly want parallel execution, you can invoke executeOnExecutor(java.util.concurrent.Executor, Object[]) with THREAD_POOL_EXECUTOR.

With that in mind, it could be that another AsyncTask is running in your app, thereby preventing this one from ever starting. That would explain why it works fine on your 2.3.5 device, but not your 4.0.4 tablet.

Upvotes: 1

Dirk J&#228;ckel
Dirk J&#228;ckel

Reputation: 3025

  1. You should not call any UI changing methods in doInBackground. Thats what onPostExecute is there for. Do only whats not allowed on the UI thread in doInBackground.

  2. To check why doInBackground is not called, please try putting the implementation (from the anonymous inner class) into LoadTast just too see if it is called then.

  3. I have implemented an AsyncWrapper by having subclasses call renamed onPostExecute and doInBackground. It should be possible to overwrite the wrapped Methods in an anonymous inner class like the one you are using in your example.

This is the short version. My real code involves some genral exception handling not only the call to the wrapped methods.

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);
  }

}

Upvotes: 2

Related Questions