Я трудился целую неделю, чтобы найти решение этой дилеммы, не прибегая к редактированию файла манифеста. Предположения для этого решения:
- Вам всегда нужно использовать диалог прогресса
- Только одна задача выполняется одновременно
- Задача должна сохраняться при повороте телефона, а диалоговое окно прогресса автоматически закрывается.
Реализация
Вам нужно будет скопировать два файла, найденные внизу этого поста, в ваше рабочее пространство. Просто убедитесь, что:
Все ваши Activity
s должны расширятьсяBaseActivity
В onCreate()
, super.onCreate()
должна вызываться после инициализации любых членов , которые нужно получить доступ к вашим ASyncTask
с. Кроме того, переопределите, getContentViewId()
чтобы предоставить идентификатор макета формы.
Переопределите, onCreateDialog()
как обычно, для создания диалогов, управляемых действием.
Посмотрите код ниже для примера статического внутреннего класса, чтобы сделать ваши AsyncTasks. Вы можете сохранить свой результат в mResult для доступа позже.
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
}
}
И наконец, чтобы запустить новое задание:
mCurrentTask = new MyTask(this);
((MyTask) mCurrentTask).execute();
Это оно! Я надеюсь, что это надежное решение поможет кому-то.
BaseActivity.java (организуйте импорт самостоятельно)
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;
}
}