J'ai peiné pendant une semaine pour trouver une solution à ce dilemme sans avoir à modifier le fichier du manifeste. Les hypothèses pour cette solution sont :
- Vous devez toujours utiliser un dialogue de progression
- Une seule tâche est exécutée à la fois
- Il faut que la tâche persiste lorsque le téléphone est tourné et que la boîte de dialogue de progression soit automatiquement fermée.
Mise en œuvre
Vous devrez copier les deux fichiers qui se trouvent au bas de cet article dans votre espace de travail. Assurez-vous que :
-
Tous vos Activity
doivent s'étendre BaseActivity
-
Sur onCreate()
, super.onCreate()
doit être appelé après l'initialisation de tous les membres qui doivent être accédés par l'utilisateur. ASyncTask
s. De plus, il faut remplacer getContentViewId()
pour fournir l'identifiant de la mise en page du formulaire.
-
Remplacer onCreateDialog()
comme d'habitude pour créer des boîtes de dialogue gérées par l'activité.
-
Voir le code ci-dessous pour un exemple de classe interne statique pour créer vos AsyncTasks. Vous pouvez stocker votre résultat dans mResult pour y accéder plus tard.
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
}
}
Et enfin, pour lancer votre nouvelle tâche :
mCurrentTask = new MyTask(this);
((MyTask) mCurrentTask).execute();
C'est ça ! J'espère que cette solution robuste pourra aider quelqu'un.
BaseActivity.java (organisez vous-même les importations)
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;
}
}