Reputation: 35
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
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
Reputation: 3025
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.
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.
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