Ich habe eine Woche lang gearbeitet, um eine Lösung für dieses Dilemma zu finden, ohne die Manifestdatei bearbeiten zu müssen. Die Annahmen für diese Lösung sind:
- Sie müssen immer einen Fortschrittsdialog verwenden
- Es wird jeweils nur eine Aufgabe ausgeführt
- Die Aufgabe muss bestehen bleiben, wenn das Telefon gedreht wird, und der Fortschrittsdialog wird automatisch geschlossen.
Implementierung
Sie müssen die beiden Dateien am Ende dieses Beitrags in Ihren Arbeitsbereich kopieren. Stellen Sie einfach sicher, dass:
Alle Ihre Activity
s sollten sich verlängernBaseActivity
In onCreate()
, super.onCreate()
sollten aufgerufen werden , nachdem Sie Mitglieder zu initialisieren , dass Bedarf von Ihrem zugegriffen werden ASyncTask
s. Überschreiben Sie außerdem getContentViewId()
, um die Formularlayout-ID anzugeben.
Überschreiben Sie onCreateDialog()
wie gewohnt , um von der Aktivität verwaltete Dialoge zu erstellen.
Im folgenden Code finden Sie ein Beispiel für eine statische innere Klasse zum Erstellen Ihrer AsyncTasks. Sie können Ihr Ergebnis in mResult speichern, um später darauf zugreifen zu können.
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
}
}
Und schließlich, um Ihre neue Aufgabe zu starten:
mCurrentTask = new MyTask(this);
((MyTask) mCurrentTask).execute();
Das ist es! Ich hoffe, diese robuste Lösung wird jemandem helfen.
BaseActivity.java (Importe selbst organisieren)
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;
}
}