I've toiled for a week to find a solution to this dilemma without resorting to editing the manifest file. The assumptions for this solution are:
- You always need to use a progress dialog
- Only one task is performed at a time
- You need the task to persist when the phone is rotated and the progress dialog to be automatically dismisses.
Implementation
You will need to copy the two files found at the bottom of this post into your workspace. Just make sure that:
All your
Activity
s should extendBaseActivity
In
onCreate()
,super.onCreate()
should be called after you initialize any members that need to be accessed by yourASyncTask
s. Also, overridegetContentViewId()
to provide the form layout id.Override
onCreateDialog()
like usual to create dialogs managed by the activity.See code below for a sample static inner class to make your AsyncTasks. You can store your result in mResult to access later.
final static class MyTask extends SuperAsyncTask<Void, Void, Void> { public OpenDatabaseTask(BaseActivity activity) { super(activity, MY_DIALOG_ID); // change your dialog ID here... // and your dialog will be managed automatically! } @Override protected Void doInBackground(Void... params) { // your task code return null; } @Override public boolean onAfterExecute() { // your after execute code }}
And finally, to launch your new task:
mCurrentTask = new MyTask(this);((MyTask) mCurrentTask).execute();
That's it! I hope this robust solution will help someone.
BaseActivity.java (organize imports yourself)
protected abstract int getContentViewId();public abstract class BaseActivity extends Activity { protected SuperAsyncTask<?, ?, ?> mCurrentTask; public HashMap<Integer, Boolean> mDialogMap = new HashMap<Integer, Boolean>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getContentViewId()); mCurrentTask = (SuperAsyncTask<?, ?, ?>) getLastNonConfigurationInstance(); if (mCurrentTask != null) { mCurrentTask.attach(this); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null&& mDialogMap.get((Integer) mCurrentTask.dialogId)) { mCurrentTask.postExecution(); } } } @Override protected void onPrepareDialog(int id, Dialog dialog) { super.onPrepareDialog(id, dialog); mDialogMap.put(id, true); } @Override public Object onRetainNonConfigurationInstance() { if (mCurrentTask != null) { mCurrentTask.detach(); if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null&& mDialogMap.get((Integer) mCurrentTask.dialogId)) { return mCurrentTask; } } return super.onRetainNonConfigurationInstance(); } public void cleanupTask() { if (mCurrentTask != null) { mCurrentTask = null; System.gc(); } }}
SuperAsyncTask.java
public abstract class SuperAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> { protected BaseActivity mActivity = null; protected Result mResult; public int dialogId = -1; protected abstract void onAfterExecute(); public SuperAsyncTask(BaseActivity activity, int dialogId) { super(); this.dialogId = dialogId; attach(activity); } @Override protected void onPreExecute() { super.onPreExecute(); mActivity.showDialog(dialogId); // go polymorphism! } protected void onPostExecute(Result result) { super.onPostExecute(result); mResult = result; if (mActivity != null && mActivity.mDialogMap.get((Integer) dialogId) != null&& mActivity.mDialogMap.get((Integer) dialogId)) { postExecution(); } }; public void attach(BaseActivity activity) { this.mActivity = activity; } public void detach() { this.mActivity = null; } public synchronized boolean postExecution() { Boolean dialogExists = mActivity.mDialogMap.get((Integer) dialogId); if (dialogExists != null || dialogExists) { onAfterExecute(); cleanUp(); } public boolean cleanUp() { mActivity.removeDialog(dialogId); mActivity.mDialogMap.remove((Integer) dialogId); mActivity.cleanupTask(); detach(); return true; }}