web-dev-qa-db-fra.com

Quand exactement onSaveInstanceState () et onRestoreInstanceState () sont-ils appelés?

La figure suivante (tirée de document officiel ) décrit le cycle de vie bien connu d'une activité Android. :

enter image description here

Par contre, lorsque l’activité est détruite par le système (par exemple parce qu’il faut récupérer de la mémoire), l’état de l’activité est parfois automatiquement sauvegardé et restauré au moyen des méthodes onSaveInstanceState() et onRestoreInstanceState(), comme illustré par la figure suivante (également de le document officiel ):

enter image description here

Je suis conscient que onSaveInstanceState() est pas toujours appelé quand une activité est sur le point d'être détruite. Par exemple, s'il est détruit parce que l'utilisateur a appuyé sur le bouton "Retour", l'état d'activité n'est pas conservé. Mais dans les cas où l’état est enregistré et restauré, et onSaveInstanceState()/onRestoreInstanceState() est appelé, lorsque exactement sont-ils appelés ?

Par exemple, selon les chiffres ci-dessus, onRestoreInstanceState() peut être appelé avant onStart(), ou après onStart() mais avant onResume() ou après onResume(). De même, il existe plusieurs possibilités pour onSaveInstanceState(). Alors, quand sont-ils appelés exactement?

Idéalement, j'aimerais voir un diagramme combiné indiquant les états du cycle de vie de l'activité et les méthodes de sauvegarde/restauration , s'il existe.

87
Luis Mendo

Selon le documentation :

void onRestoreInstanceState (Bundle savedInstanceState)

Cette méthode est appelée entre onStart() et onPostCreate(Bundle).

void onSaveInstanceState (Bundle outState)

Si elle est appelée, cette méthode sera utilisée après onStop () pour les applications ciblant les plates-formes commençant par Build.VERSION_CODES.P. Pour les applications ciblant des versions de plate-forme antérieures, cette méthode sera utilisée avant onStop () et rien ne garantit que cela se produira avant ou après onPause ().

90
Steve M

Selon doc1 et doc2

onSaveInstanceState

Avant Honeycomb, les activités n'étaient considérées comme meurtrières qu'après leur pause, ce qui signifie que onSaveInstanceState () était appelée immédiatement avant onPause (). Cependant, à partir de Honeycomb, les activités sont considérées comme meurtrières uniquement après leur arrêt, ce qui signifie que onSaveInstanceState () sera maintenant appelé avant onStop () au lieu d'être immédiatement avant onPause ().

onRestoreInstanceState

Cette méthode est appelée entre onStart () et onPostCreate (Bundle) lorsque l'activité est en cours de réinitialisation à partir d'un état précédemment enregistré.

15
Android Developer

En plus des réponses déjà postées, un changement subtil a été introduit dans Android P, qui est:

void onSaveInstanceState (Bundle outState)

Si elle est appelée, cette méthode aura lieu [~ # ~] après [~ # ~] onStop() pour les applications ciblant les plates-formes commençant par [~ # ~] p [~ # ~] . Pour les applications ciblant des versions antérieures de la plate-forme, cette méthode sera utilisée avant onStop() et rien ne garantit que cela se produira avant ou après onPause().

Source: docs

Pour expliquer pourquoi ce changement est introduit, voici la réponse:

... ainsi, une application peut effectuer en toute sécurité des transactions de fragment dans onStop() et pourra sauvegarder l'état persistant ultérieurement.

Source: docs

12
azizbekian

Ceci est une information supplémentaire pour onSaveInstanceState (Bundle)

de docs

Ne confondez pas cette méthode avec les rappels du cycle de vie d'une activité tels que onPause (), qui est toujours appelée lorsqu'une activité est placée en arrière-plan ou sur le point d'être détruite, ou onStop () qui est appelée avant la destruction. Par exemple, lorsque onPause () et onStop () sont appelées, cette méthode n’est pas utilisée lorsqu'un utilisateur revient de l’activité B à l’activité A: il n’est pas nécessaire d’appeler onSaveInstanceState (Bundle) sur B car cette instance particulière ne sera jamais restaurée. , afin que le système évite de l'appeler. Un exemple lorsque onPause () est appelé et non onSaveInstanceState (Bundle), c’est lorsque l’activité B est lancée devant l’activité A: le système peut éviter d’appeler onSaveInstanceState (Bundle) sur l’activité A si elle n’a pas été supprimée pendant la durée de vie de B, car l'état de l'interface utilisateur de A restera intact.

Donc, c'est l'implémentation par défaut pour ..

L'implémentation par défaut prend en charge la plupart des états d'interface utilisateur par instance en appelant onSaveInstanceState () sur chaque vue de la hiérarchie dotée d'un identifiant, et en enregistrant l'identifiant de la vue actuellement focalisée (le tout étant restauré par la hiérarchie). implémentation par défaut de onRestoreInstanceState (Bundle)). Si vous substituez cette méthode pour enregistrer des informations supplémentaires non capturées par chaque vue, vous souhaiterez probablement appeler jusqu'à l'implémentation par défaut. Sinon, préparez-vous à enregistrer vous-même tout l'état de chaque vue.

5
Mahmoud Mzz
String activityState;
@Override 
public void onCreate(Bundle savedInstanceState) {
// call the super class onCreate to complete the creation of activity like 
// the view hierarchy 
super.onCreate(savedInstanceState);

// recovering the instance state 
if (savedInstanceState != null) {
     activityState = savedInstanceState.getString(STATE_KEY);
 } 

   setContentView(R.layout.main_activity);
   mTextView = (TextView) findViewById(R.id.text_view);
} 

// Ce rappel n'est appelé que s'il existe une instance enregistrée précédemment enregistrée avec // onSaveInstanceState (). Nous restaurons un état dans onCreate () alors que nous pouvons éventuellement restaurer // un autre état ici, éventuellement utilisable après la fin de onStart (). // Le paquet savedInstanceState est identique à celui utilisé dans onCreate ().

@Override 
public void onRestoreInstanceState(Bundle savedInstanceState) {
 mTextView.setText(savedInstanceState.getString(STATE_KEY));
  } 


// invoked when the activity may be temporarily destroyed, save the instance 
//state here 
//this method will be called before onstop

@Override 
 public void onSaveInstanceState(Bundle outState) {
    outState.putString(STATE_KEY, activityState);

    // call superclass to save any view hierarchy 
    super.onSaveInstanceState(outState);
} 
0
parvez rafi