web-dev-qa-db-fra.com

Comment restaurer une pile de fragments dans une activité (après la suppression de l'application en arrière-plan)

Dans une application Android

Dites que je suis dans une Activity - MyActivity qui contient une Fragment à la fois.

J'ai tout d'abord chargé Fragment A (Sans balise, je l'ai ajouté pour sauvegarder la pile de la variable FragmentManager)

Puis, à un moment donné, j'ai chargé Fragment B (encore une fois sans balises, je l'ai ajouté pour sauvegarder la pile de la FragmentManager)

Puis, à un moment donné, j'ai chargé Fragment C (De nouveau sans balises, je l'ai ajouté pour sauvegarder la pile de la FragmentManager)

J'utilise popBackStack() pour activer bouton Précédent comportement, donc chaque fois que j'appuie sur Fragment C le flux est comme:

Fragment C -> Fragment B -> Fragment A -> Fermer MonActivité ..

Tout est parfait :-)

Mais si je suis dans Fragment C et l'application obtient tué en arrière-plan (j'ai utilisé "ne pas garder l'indicateur d'activité" dans les paramètres)

et revenir en ligne le fragment C est chargé dans MyActivity

mais la pile arrière de FragmentManager contient uniquement Fragment C ..

Le bouton Précédent le décoiffe

Fragment C -> Fermez MyActivity ..

Pourquoi est-ce? 

Comment restaurer correctement la pile de retour de FragmentManager dans une Activity?

14
Arun C

Essayez d’utiliser alwaysRetainTaskState sur votre activité racine. Android efface automatiquement le backstack de l'activité, car il suppose que cela fait longtemps que vous utilisez l'application et que l'utilisateur souhaite recommencer depuis le début.

 <activity Android:alwaysRetainTaskState="true"/>

Ce paramètre empêchera ce comportement et il s'ensuit que le comportement est hérité par le gestionnaire de fragments.

11
shredder

Lors du développement de votre application, je vous recommande de tester les états de restauration/d'enregistrement des activités, fragments avec ADB:

  1. Ouvrir application
  2. Naviguer entre les activités
  3. Presse accueil
  4. BAD -> Kill (stop) app
  5. Appuyez sur la pile d'applications (bouton de menu de l'appareil) et relancez l'application.

De cette façon, vous pouvez déboguer les états sauvegardés/restaurés.

Si vous n'avez pas d'application complexe, je vous suggère de gérer l'état de sauvegarde/restauration dans l'activité:

private Fragment1 mFragment;

@Override
protected void onCreate(Bundle savedState) {
   super.onCreate(savedState);
   // ...

   if (savedState == null) {
       mFragment = new Fragment1();

       getFragmentManger().beginTransacation().add(mFragment, TAG).addToBackStack(TAG).commit();
   }
   else {
       mFragment = getFragmentMananager().findFragmentByTag(TAG);
   }
}

Si vous avez plusieurs Fragments ou un ViewPager ou des fragments imbriqués, les choses peuvent devenir vraiment compliquées. Je vous suggère de redémarrer toute l'application:

@Override
protected void onCreate(Bundle savedState) {
   super.onCreate(savedState);

   if (savedState != null) {
      Intent intent = new Intent(ActivityMain.this, ActivityMain.class);
      intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
      startActivity(intent);

      return;
   }
}

Si vous souhaitez gérer chaque état enregistré/restauré, veuillez lire le message suivant: http://www.androiddesignpatterns.coms.com/138/08/fragment-transaction-commit-state-loss.html

4
Zbarcea Christian

essayez cette méthode

public void setRetainInstance (boolean retain)

Contrôlez si une instance de fragment est conservée lors de la recréation d'activités (par exemple, à la suite d'un changement de configuration). Cela ne peut être utilisé qu'avec des fragments qui ne sont pas dans la pile arrière. Si défini, le cycle de vie des fragments sera légèrement différent lorsqu’une activité est recréée:

sur le site Web du développeur http://developer.Android.com/reference/Android/app/Fragment.html#setRetainInstance%28boolean%29

1
Moinkhan

Le fragment C ne doit jamais être chargé après la mort de votre application. Avez-vous un fragment Init dans votre application? Idéalement, lorsque vous implémentez une série de fragments, il devrait y avoir un écran Init. Si l'application meurt ou est supprimée pour des raisons de mémoire, vous devez commencer par le fragment A (fragment d'init). Pas du fragment C.

Si votre problème exige cette solution, vous devriez alors enregistrer chaque fragment de manière persistante lorsqu'un nouveau fragment arrive en haut. Ce qui, idéalement, signifie que vous persistez dans votre backstack dans une préférence ou une base de données pour y parvenir.

0
user1649464