2010-02-26 4 views
12

1) Je lance une tâche d'arrière-plan (via AsyncTask)Rejeter dialogue après le changement d'orientation de l'écran

new FindJourneyTask().execute(); // FindJourneyTask extends AsyncTask 

2) Toujours dans le thread principal (juste avant nouveau thread est lancé) je crée une boîte de dialogue avec showDialog (dialogId)

// this method is in FindJourneyTask 
protected void onPreExecute() { 
    showDialog(DIALOG_FINDING_JOURNEY); 
} 

3) les changements d'orientation de l'écran et l'activité est recréée

4) Comment puis-je rejeter maintenant la boîte de dialogue de la FindJourneyTask? L'appel de rejectDialog (dialogId) ne fait rien.

// this method is in FindJourneyTask 
protected void onPostExecute(FindJourneyResult result) { 
    dismissDialog(DIALOG_FINDING_JOURNEY); // does nothing 
} 
+0

Postez votre code afin que nous puissions voir ce que vous faites mal. –

Répondre

22

Ceci est un problème courant, et il n'y a pas vraiment de bonnes solutions. Le problème est que sur le changement d'orientation à l'écran, toute l'activité est détruite et recréée. En même temps, le dialogue que vous aviez précédemment est recréé dans la nouvelle activité, mais l'ancienne tâche d'arrière-plan fait toujours référence à l'ancienne activité lorsqu'elle tente de fermer la boîte de dialogue. Le résultat est qu'il supprime un dialogue qui a été détruit il y a longtemps, plutôt que de rejeter le dialogue de la nouvelle orientation créée.

Il existe trois solutions de base:

  1. Remplacer l'orientation du code de manipulation par défaut afin que votre activité ne soit pas détruite lors de la rotation. C'est probablement la réponse la moins satisfaisante, car elle bloque beaucoup de code qui est automatiquement exécuté lors des changements d'orientation.

  2. Créez une variable membre statique de votre activité qui fait référence à l'activité elle-même. Vous pouvez donc appeler STATIC_ACTIVITY_VARIABLE.dismissDialog().

  3. Codez une solution dans laquelle la tâche d'arrière-plan garde trace de l'activité en cours et se met à jour si nécessaire.

Ces trois solutions sont discutées longuement ici: http://groups.google.com/group/android-developers/browse_thread/thread/bf046b95cf38832d/

+0

J'ai fait de mon dialogue une variable statique dans mon activité, et cela fonctionne parfaitement maintenant. par exemple. static AlertDialog dlg_error = null; – Kevin

10

Il y a une meilleure solution à ce problème maintenant qui consiste à utiliser des fragments.

Si vous créez une boîte de dialogue à l'aide de DialogFragment, ce fragment sera responsable du maintien du cycle de vie de votre boîte de dialogue. Lorsque vous affichez une boîte de dialogue, vous fournissez une étiquette pour votre fragment (DialogFragment.show()). Lorsque vous avez besoin d'accéder à votre boîte de dialogue, il suffit de chercher le DialogFragment nécessaire en utilisant FragmentManager.findFragmentByTag au lieu d'avoir une référence à la boîte de dialogue elle-même. De cette façon, si le périphérique change d'orientation, vous obtiendrez un nouveau fragment à la place de l'ancien, et tout fonctionnera.

est ici un code basé également en réponse @peresisUser:

public void onSaveInstanceState(Bundle outState) { 
    AppCompatActivity activity = (AppCompatActivity) context; 
    FragmentManager fragmentManager = activity.getSupportFragmentManager(); 
    DialogFragment dialogFragment = (DialogFragment) fragmentManager.findFragmentByTag("your_dialog_tag"); 
    if(dialogFragment!=null) { 
     Dialog dialog = dialogFragment.getDialog(); 
     if(dialog!=null && dialog.isShowing()) { 
     dialogFragment.dismiss(); 
     } 
    } 
} 
+1

J'ai eu le même problème même en utilisant des fragments. Quand l'activité est recréée et essaye de trouver le fragment par tag, je reçois toujours une référence nulle avec le dialogue montré dans la nouvelle activité O_o – fr4gus

+0

@ fr4gus C'est probablement un bug, il va falloir expérimenter avec des choses pour trouver une solution de contournement. – Malcolm

4

C'est longtemps après que la question a été posée et a répondu, mais je suis tombé sur ce problème aussi et je voulais partager ma solution ...

Je vérifie onSavedInstance() qui s'exécute lors du changement d'orientation, que la boîte de dialogue soit affichée ou non avec dialog.isShowing(), et la passe dans la variable outState. Ensuite, dans votre onCreate(), vous vérifiez cette var si c'est vrai. Si c'est le cas, il vous suffit de fermer votre boîte de dialogue avec le dialogue.dismiss()

Espérons que cela aide les autres :()

Questions connexes