Ho lavorato duramente per una settimana per trovare una soluzione a questo dilemma senza ricorrere alla modifica del file manifest. I presupposti per questa soluzione sono:
- È sempre necessario utilizzare una finestra di dialogo di avanzamento
- Viene eseguita una sola attività alla volta
- È necessario che l'attività persista quando il telefono viene ruotato e la finestra di dialogo di avanzamento viene automaticamente chiusa.
Implementazione
Dovrai copiare i due file trovati in fondo a questo post nel tuo spazio di lavoro. Assicurati solo che:
Tutti i tuoi messaggi Activity
dovrebbero estendersiBaseActivity
In onCreate()
, super.onCreate()
dovrebbe essere chiamato dopo aver inizializzato tutti i membri a cui è necessario accedere dai propri messaggi ASyncTask
. Inoltre, eseguire getContentViewId()
l' override per fornire l'ID del layout del modulo.
Sostituisci onCreateDialog()
come al solito per creare finestre di dialogo gestite dall'attività.
Vedi il codice sotto per una classe interna statica di esempio per creare i tuoi AsyncTasks. È possibile memorizzare i risultati in mResult per accedervi in un secondo momento.
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
}
}
E infine, per avviare la tua nuova attività:
mCurrentTask = new MyTask(this);
((MyTask) mCurrentTask).execute();
Questo è tutto! Spero che questa soluzione solida possa aiutare qualcuno.
BaseActivity.java (organizza tu stesso le importazioni)
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;
}
}