web-dev-qa-db-fra.com

Perte de données lors de la rotation de l'écran

J'ai un petit bug drôle dans mon application. Lorsque l'utilisateur fait pivoter l'écran, je perds certaines des données de mon activité. Quiconque a une idée de pourquoi cela se produit?

35
Roland

Par défaut, lorsque l'écran pivote, votre activité est supprimée et redémarrée. Pour vous assurer qu'aucune donnée n'est perdue, vous devez enregistrer et restaurer correctement vos données à l'aide des méthodes de cycle de vie. Voir Enregistrement de l'état persistant .

33
Cheryl Simon
//Use onSaveInstanceState(Bundle) and onRestoreInstanceState

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {

  // Save UI state changes to the savedInstanceState.   
  // This bundle will be passed to onCreate if the process is  
  // killed and restarted.

  savedInstanceState.putBoolean("MyBoolean", true);  
  savedInstanceState.putDouble("myDouble", 1.9);  
  savedInstanceState.putInt("MyInt", 1);  
  savedInstanceState.putString("MyString", "Welcome back to Android");  

  // etc.  

  super.onSaveInstanceState(savedInstanceState);  
}  

//onRestoreInstanceState  

@Override  
public void onRestoreInstanceState(Bundle savedInstanceState) {  

  super.onRestoreInstanceState(savedInstanceState);  

  // Restore UI state from the savedInstanceState.  
  // This bundle has also been passed to onCreate.  

  boolean myBoolean = savedInstanceState.getBoolean("MyBoolean");  
  double myDouble = savedInstanceState.getDouble("myDouble");  
  int myInt = savedInstanceState.getInt("MyInt");  
  String myString = savedInstanceState.getString("MyString");  
}

C'est ainsi que vous enregistrez vos données lorsque le système les supprime lors de la rotation.

67
jaisonDavis

La solution la plus rapide que j'ai trouvée est la suivante: http://developer.Android.com/guide/topics/resources/runtime-changes.html#HandlingTheChange

8
Theodor Paulus

Voici une variante de la réponse utile de @ jaisonDavis:

int myInt;
String myString;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_verses);


    if (savedInstanceState == null) {

        Intent intent = getIntent();
        myInt = intent.getIntExtra("MyIntIntentKey", DEFAULT_INT);
        myString = intent.getStringExtra("MyStringIntentKey", DEFAULT_STRING);

    } else { // savedInstanceState has saved values

        myInt = savedInstanceState.getInt("MyIntKey");
        myString = savedInstanceState.getString("MyStringKey");
    }

}

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {

    savedInstanceState.putInt("MyIntKey", myInt);
    savedInstanceState.putString("MyStringKey", myString);

    super.onSaveInstanceState(savedInstanceState);
}

Dans cet exemple, les variables sont initialisées à partir d'un Intent lors de la première création de l'activité, mais après cela, elles sont initialisées à partir de savedInstanceState (comme lorsque l'orientation change).

7
Suragch

Dans le AndroidManifest.xml ajoutez le code suivant

<activity Android:name=".MainActivity" Android:configChanges="keyboardHidden|orientation|screenSize" >

5
sameer tzar

Plus de détails

Les gens ont déjà fourni le code. Je vais donc ajouter plus de détails à ce sujet.

Que se passe-t-il lorsque l'écran tourne?

Lorsque l'écran pivote, la configuration de l'activité change afin que le système recherche une ressource plus appropriée pour l'activité. À cet effet, le système tue l'instance de l'activité et recrée une nouvelle instance de l'activité.

Comment le système crée-t-il une nouvelle instance?

Le système tente de recréer l'instance à l'aide d'un ensemble de données enregistrées de l'ancienne instance d'activité appelée état d'instance . InstanceState est une collection de paires valeur/clé stockées dans un objet Bundle.

Le système a enregistré automatiquement certaines données

Par défaut, System enregistre les objets View dans le Bundle par exemple.

  • Texte dans EditText
  • Position de défilement dans un ListView, etc.

Si vous souhaitez stocker plus de données qui devraient survivre au changement d'orientation. Vous devez remplacer la méthode onSaveInstanceState(Bundle savedInstanceState).

Utilisez onSaveInstaneState correctement

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save the user's current game state
    savedInstanceState.putInt(STATE_SCORE, mCurrentScore);

    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(savedInstanceState);
}

Donc, par erreur, si vous oubliez d'appeler super.onSaveInstanceState (savedInstanceState), le comportement par défaut ne fonctionnera pas, c'est-à-dire que le texte dans EditText ne sera pas enregistré. Si vous ne me croyez pas regardez ça

Quelle méthode utiliser pour restaurer l'état?

Beaucoup de gens sont confus, y compris moi. Dois-je choisir

  • onCreate(Bundle savedInstanceState)

OR

  • onRestoreInstanceState(Bundle savedInstanceState)

Peu importe . Les deux méthodes reçoivent le même bundle dans le paramètre. La seule différence est que vous devez fournir une vérification nulle dans la méthode onCreate(Bundle savedInstanceState). Mais si vous allez utiliser onRestoreInstanceState(Bundle savedInstanceState), utilisez-le soigneusement

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    // Always call the superclass so it can restore the view hierarchy
    super.onRestoreInstanceState(savedInstanceState);

    // Restore state members from saved instance
    mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
}

Appelez toujours super.onRestoreInstanceState(savedInstanceState) pour que le système rétablisse la hiérarchie des vues par défaut

3
Rohit Singh

Dans AndroidManifest.xml, ajoutez le code suivant

<activity Android:name=".MainActivity"
            Android:configChanges="keyboardHidden|orientation|screenSize"
            >

Ça marche pour moi

2
Float
setRetainInstance(true);

Utilisez-le sur OnCreate

2
saurabh yadav

Android a introduit ViewModel qui peut stocker des objets complexes lorsque l'écran est tourné. La classe ViewModel est conçue pour stocker et gérer les données liées à l'interface utilisateur en tenant compte du cycle de vie. La classe ViewModel permet aux données de survivre aux changements de configuration tels que les rotations d'écran.

Veuillez vous référer aux documents

https://developer.Android.com/topic/libraries/architecture/viewmodel

1
Nudge

Vous pouvez utiliser le modèle MVVM et utiliser votre ViewModel pour enregistrer vos données. Ainsi, lorsque vous faites pivoter votre appareil, vous ne craindrez pas de perdre vos données car vous avez isolé vos données dans le ViewModel et cela signifie que vos données ne seront pas affectées par le cycle de vie de l'activité. https://developer.Android.com/topic/libraries/architecture/viewmodel

0
Ali Mansour