Comment utiliser l'exemple onSavedInstanceState s'il vous plaît

110

Je suis confus quand il s'agit de sauver un état. Je sais donc que cela onSaveInstanceState(Bundle)s'appelle lorsque l'activité est sur le point d'être détruite. Mais comment y stocker vos informations et les ramener à leur état d'origine onCreate(Bundle savedInstanceState)? Je ne comprends pas comment cet ensemble restaurera les informations. Il serait utile que quelqu'un puisse donner un exemple. Le guide des développeurs ne fait pas un bon travail pour expliquer cela.

public class Conversation extends Activity {
    private ProgressDialog progDialog;
    int typeBar;
    TextView text1;
    EditText edit;
    Button respond;
    private String name;
    private String textAtView;
    private String savedName;

    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        setContentView(R.layout.dorothydialog);
        text1 = (TextView)findViewById(R.id.dialog);
        edit = (EditText)findViewById(R.id.repsond);
        respond = (Button)findViewById(R.id.button01);

        if(savedInstanceState != null){
            savedInstanceState.get(savedName);
            text1.setText(savedName);
        }
        else{
            text1.setText("Hello! What is your name?");
            respond.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    name = edit.getText().toString();
                    text1.setText("Nice to meet you "+ name);
                }   
            });
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState){
        super.onSaveInstanceState(outState);
        outState.putString(savedName, name);
    }
}
marcheur tj
la source
text1.setText (savedInstanceState.getString (savedName));
Spidy
@Spidy Et onBackpressed? Comment réagirais-je à cela avec l'offre groupée?
tj walker le
Vous ne le feriez pas. Lorsque l'utilisateur appuie sur le bouton de retour. L'activité est tuée. Utilisez une base de données pour le stockage permanent des données. Utilisez le bundle pour ramener une application redémarrée à son état précédent.
Spidy

Réponses:

198

Le Bundleest un conteneur pour toutes les informations que vous souhaitez enregistrer. Vous utilisez les fonctions put * pour y insérer des données. Voici une courte liste (il y en a plus) des fonctions put que vous pouvez utiliser pour stocker des données dans le Bundle.

putString
putBoolean
putByte
putChar
putFloat
putLong
putShort
putParcelable (used for objects but they must implement Parcelable)

Dans votre onCreatefonction, cela Bundleest rendu au programme. La meilleure façon de vérifier si l'application est en cours de rechargement ou de démarrage pour la première fois est:

if (savedInstanceState != null) {
    // Then the application is being reloaded
}

Pour récupérer les données, utilisez les fonctions get * comme les fonctions put *. Les données sont stockées sous forme de paire nom-valeur. C'est comme un hashmap. Vous fournissez une clé et la valeur, puis lorsque vous souhaitez récupérer la valeur, vous donnez la clé et la fonction obtient la valeur. Voici un petit exemple.

@Override
public void onSaveInstanceState(Bundle outState) {
   outState.putString("message", "This is my message to be reloaded");
   super.onSaveInstanceState(outState);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        String message = savedInstanceState.getString("message");
        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
    }
}

Votre message enregistré sera grillé à l'écran. J'espère que cela t'aides.

Spidy
la source
14
onSaveInstanceState () est appelé avant que votre activité ne soit suspendue. Ainsi, toutes les informations dont il a besoin après avoir été potentiellement détruites peuvent être récupérées à partir du bundle enregistré
Diederik
@Spidy génial! Vous m'avez vraiment fait comprendre tout sur un bundle! alors je suppose que outState est renvoyé au bundle savedInstanceState? Correct?
tj walker le
Oui. Le bundle outState est renvoyé en tant que bundle savedInstanceState
Spidy
1
@tj walker - Les livres de référence techniques sont une autre excellente ressource. Pro Android 3 est une ressource bon marché mais complète que vous pouvez obtenir sur Amazon
Spidy
@Spidy J'ai publié mon code d'activité ci-dessus pour que vous puissiez le voir. Vous pouvez peut-être me faire savoir si je sauve mon état correctement, comme vous l'avez suggéré.
tj walker le
34

Une remarque majeure que tous les nouveaux développeurs Android doivent savoir est que toutes les informations contenues dans les widgets (TextView, boutons, etc.) seront conservées automatiquement par Android tant que vous leur attribuez un identifiant. Cela signifie que la plupart de l'état de l'interface utilisateur est pris en charge sans problème. Ce n'est que lorsque vous avez besoin de stocker d'autres données que cela devient un problème.

Depuis Android Docs :

Le seul travail requis par vous est de fournir un identifiant unique (avec l'attribut android: id) pour chaque widget dont vous souhaitez enregistrer son état. Si un widget n'a pas d'identifiant, il ne peut pas enregistrer son état

Keith Adler
la source
1
Eh bien, est-ce vraiment vrai? Parce que j'ai une activité avec un bouton textview et modifier le texte. Si l'application est détruite ou tuée, tout est remis dans son état d'origine. Dans mon application, les textes textView changent à chaque fois que l'utilisateur clique sur le bouton.
tj walker le
La documentation est-elle inexacte? Je n'ai jamais vu une vue enregistrer ses propres informations. Votre meilleur pari est de sauvegarder toutes vos informations vous-même à mon avis.
Spidy le
2
Si votre objectif est d'enregistrer des informations surSaveInstanceState n'est PAS l'endroit pour le faire. C'est parce qu'il n'y a aucune garantie qu'il sera appelé (voir la documentation). Vous devriez plutôt écrire dans une base de données, SharedPreferences, etc. Oui, ces informations sont exactes. La meilleure façon de vérifier si votre interface utilisateur persiste de cette manière est de faire pivoter votre affichage lorsque les changements d'orientation réexécutent votre onCreate et d'utiliser le bundle pour restaurer l'état.
Keith Adler le
@Nissan Fan pouvez-vous donner un exemple comme Spidy l'a fait ci-dessus? Avec les sharedprefs et tout? Merci
tj walker
Les meilleurs exemples proviennent très franchement de la documentation. developer.android.com/guide/topics/data/data-storage.html#pref
Keith Adler
6

Une bonne information: vous n'avez pas besoin de vérifier si l'objet Bundle est nul dans la méthode onCreate (). Utilisez la méthode onRestoreInstanceState (), que le système appelle après la méthode onStart (). Le système appelle onRestoreInstanceState () uniquement s'il y a un état enregistré à restaurer, vous n'avez donc pas besoin de vérifier si le Bundle est nul

Diego Souza
la source
5

Informations sur le magasin:

static final String PLAYER_SCORE = "playerScore";
static final String PLAYER_LEVEL = "playerLevel";

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

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

Si vous ne souhaitez pas restaurer les informations dans votre méthode onCreate:

Voici les exemples: Recréer une activité

Au lieu de restaurer l'état pendant onCreate (), vous pouvez choisir d'implémenter onRestoreInstanceState (), que le système appelle après la méthode onStart (). Le système appelle onRestoreInstanceState () uniquement s'il y a un état enregistré à restaurer, vous n'avez donc pas besoin de vérifier si le Bundle est nul

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(PLAYER_SCORE);
mCurrentLevel = savedInstanceState.getInt(PLAYER_LEVEL);
}
Klatschen
la source
0

Fondamentalement, onSaveInstanceState (Bundle outBundle) vous donnera un bundle. Lorsque vous regardez la classe Bundle, vous verrez que vous pouvez y mettre beaucoup de choses différentes. Lors du prochain appel de onCreate (), vous récupérez simplement ce Bundle en tant qu'argument. Ensuite, vous pouvez relire vos valeurs et restaurer votre activité.

Disons que vous avez une activité avec un EditText. L'utilisateur a écrit du texte à l'intérieur. Après cela, le système appelle votre onSaveInstanceState (). Vous lisez le texte du EditText et l'écrivez dans le Bundle via Bundle.putString ("edit_text_value", theValue).

Maintenant onCreate est appelé. Vous vérifiez si le bundle fourni n'est pas nul. Si tel est le cas, vous pouvez restaurer votre valeur via Bundle.getString ("edit_text_value") et la remettre dans votre EditText.


la source
0

Ceci est pour des informations supplémentaires.

Imaginez ce scénario

  1. ActivityA lancer ActivityB.
  2. ActivityB lance une nouvelle ActivityAPrime by

    Intent intent = new Intent(getApplicationContext(), ActivityA.class);
    startActivity(intent);
  3. ActivityAPrime n'a aucune relation avec ActivityA.
    Dans ce cas, le Bundle dans ActivityAPrime.onCreate () sera nul.

Si ActivityA et ActivityAPrime doivent être la même activité au lieu d'activités différentes, ActivityB doit appeler finish () plutôt que startActivity ().

Ken
la source
juste pour clarifier, dans votre exemple, ActivityA == ActivityA instance 1 et ActivityAPrime == ActivityA instance 2? aussi, quand vous dites, "ActivityB devrait appeler finish () que d'utiliser startActivity ()." voulez-vous dire: (1) AcitivityB devrait appeler finish () puis utiliser startActivity () après (2) ou ActivityB devrait appeler finish () plutôt que d'utiliser startActivity () du tout? si vous vouliez dire l'option 2, comment suggéreriez-vous à quelqu'un de redémarrer la même instance1 de ActivityA pour pouvoir charger les données que l'activité contenait avant d'être détruite / terminée? Merci
cjayem13
ActivityA et ActivityAPrime sont de la même classe mais des instances différentes. Dans ce scénario, ActivityA n'est pas encore terminé ses activités, au milieu de celui-ci, il a créé et démarré ActivityB, donc lorsque ActivityB a terminé, ActivityA devrait continuer son activité restante. Il est faux d'appeler startActivity dans ce cas et de s'attendre à ce que ActivityA et ActiviyAPrime soient la même instance. nous ne devons donc pas redémarrer ActivityA, juste terminer ActivityB et laisser ActivityA reprendre son fonctionnement ...
ken
0

Si les données ne sont pas chargées depuis, savedInstanceStateutilisez le code suivant.
Le problème est que l'appel d'URL ne se termine pas complètement, alors vérifiez si les données sont chargées, puis affichez la valeur instanceState.

//suppose data is not Loaded to savedInstanceState at 1st swipe
if (savedInstanceState == null && !mAlreadyLoaded){
    mAlreadyLoaded = true;
    GetStoryData();//Url Call
} else {
    if (listArray != null) {  //Data Array From JsonArray(ListArray)
        System.out.println("LocalData  " + listArray);
        view.findViewById(R.id.progressBar).setVisibility(View.GONE);
    }else{
        GetStoryData();//Url Call
    }
}
Mathan Chinna
la source