Wie verwende ich bitte das Beispiel onSavedInstanceState?

110

Ich bin verwirrt, wenn es darum geht, einen Staat zu retten. Ich weiß also, dass dies onSaveInstanceState(Bundle)aufgerufen wird, wenn die Aktivität zerstört werden soll. Aber wie speichern Sie Ihre Informationen darin und bringen sie in ihren ursprünglichen Zustand zurück onCreate(Bundle savedInstanceState)? Ich verstehe nicht, wie dieses Bundle Informationen wiederherstellt. Es wäre hilfreich, wenn jemand ein Beispiel geben könnte. Der Dev-Guide erklärt dies nicht gut.

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);
    }
}
tj walker
quelle
text1.setText (savedInstanceState.getString (savedName));
Spidy
@Spidy Was ist mit onBackpressed? Wie würde ich mit dem Bundle darauf reagieren?
tj Walker
Das würdest du nicht. Wenn der Benutzer die Zurück-Taste drückt. Die Aktivität wird getötet. Verwenden Sie eine Datenbank zur dauerhaften Datenspeicherung. Verwenden Sie das Bundle, um eine neu gestartete Anwendung auf ihren vorherigen Status zurückzusetzen.
Spidy

Antworten:

197

Das Bundleist ein Container für alle Informationen, die Sie speichern möchten. Mit den Funktionen put * fügen Sie Daten ein. Hier ist eine kurze Liste (es gibt mehr) von Put-Funktionen, mit denen Sie Daten in der speichern können Bundle.

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

In Ihrer onCreateFunktion ist diesBundle an das Programm zurückgegeben. Der beste Weg, um zu überprüfen, ob die Anwendung neu geladen oder zum ersten Mal gestartet wird, ist:

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

Verwenden Sie die get * -Funktionen genau wie die put * -Funktionen, um die Daten wieder herauszuholen. Die Daten werden als Name-Wert-Paar gespeichert. Das ist wie eine Hashmap. Sie geben einen Schlüssel und den Wert an. Wenn Sie den Wert zurückgeben möchten, geben Sie den Schlüssel an und die Funktion erhält den Wert. Hier ist ein kurzes Beispiel.

@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();
    }
}

Ihre gespeicherte Nachricht wird auf den Bildschirm geröstet. Hoffe das hilft.

Spidy
quelle
14
onSaveInstanceState () wird aufgerufen, bevor Ihre Aktivität angehalten wird. So können alle Informationen, die es benötigt, nachdem es möglicherweise zerstört wurde, aus dem gespeicherten Bundle
Diederik
@ Spidy Awesome! Du hast mich wirklich dazu gebracht, alles über ein Bündel zu verstehen! Vermutlich wird outState an das Paket "savedInstanceState" zurückgegeben? Richtig?
tj
Ja. Das outState Bundle wird als savedInstanceState Bundle
Spidy
1
@tj walker - Eine weitere großartige Ressource sind technische Nachschlagewerke. Pro Android 3 ist eine billige, aber umfangreiche Ressource, die Sie bei Amazon bekommen können
Spidy
@ Spidy Ich habe oben meinen Aktivitätscode gepostet, damit Sie ihn sehen können. Vielleicht können Sie mich wissen lassen, ob ich meinen Staat richtig rette, wie Sie vorgeschlagen haben.
tj walker
34

Ein wichtiger Hinweis, den alle neuen Android-Entwickler wissen sollten, ist, dass alle Informationen in Widgets (TextView, Schaltflächen usw.) von Android automatisch beibehalten werden, solange Sie ihnen eine ID zuweisen. Das bedeutet, dass der größte Teil des UI-Status ohne Probleme erledigt wird. Nur wenn Sie andere Daten speichern müssen, wird dies zu einem Problem.

Von Android Docs :

Sie müssen lediglich eine eindeutige ID (mit dem Attribut android: id) für jedes Widget angeben, dessen Status Sie speichern möchten. Wenn ein Widget keine ID hat, kann es seinen Status nicht speichern

Keith Adler
quelle
1
Nun, ist das wirklich wahr? Weil ich eine Aktivität mit einer Schaltfläche Textansicht habe und Text bearbeite. Wenn die Anwendung zerstört oder beendet wird, wird alles in den ursprünglichen Zustand zurückversetzt. In meiner Anwendung ändern sich die textView-Texte jedes Mal, wenn der Benutzer auf die Schaltfläche klickt.
tj walker
Ist die Dokumentation ungenau? Ich habe noch nie eine Ansicht ihre eigenen Informationen speichern lassen. Am besten speichern Sie meiner Meinung nach alle Ihre Informationen selbst.
Spidy
2
Wenn Sie Informationen auf SaveInstanceState speichern möchten, ist dies NICHT der richtige Ort. Dies liegt daran, dass es keine Garantie dafür gibt, dass es aufgerufen wird (siehe Dokumente). Sie sollten stattdessen in eine Datenbank, SharedPreferences usw. schreiben. Ja, diese Informationen sind korrekt. Der beste Weg, um zu testen, ob Ihre Benutzeroberfläche auf diese Weise bestehen bleibt, besteht darin, die Anzeige zu drehen, wenn sich die Ausrichtung ändert. Führen Sie onCreate erneut aus und verwenden Sie das Bundle, um den Status wiederherzustellen.
Keith Adler
@ Nissan Fan kannst du ein Beispiel geben, wie es Spidy oben getan hat? Mit den Sharedprefs und allem? Danke
tj walker
Die besten Beispiele stammen ganz offen aus der Dokumentation. developer.android.com/guide/topics/data/data-storage.html#pref
Keith Adler
6

Eine gute Information: Sie müssen in der onCreate () -Methode nicht überprüfen, ob das Bundle-Objekt null ist. Verwenden Sie die Methode onRestoreInstanceState (), die das System nach der Methode onStart () aufruft. Das System ruft onRestoreInstanceState () nur auf, wenn ein gespeicherter Status wiederhergestellt werden muss, sodass Sie nicht überprüfen müssen, ob das Bundle null ist

Diego Souza
quelle
5

Information speichern:

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);
}

Wenn Sie keine Informationen in Ihrer onCreate-Methode wiederherstellen möchten:

Hier sind die Beispiele: Neuerstellung einer Aktivität

Anstatt den Status während onCreate () wiederherzustellen, können Sie onRestoreInstanceState () implementieren, das das System nach der onStart () -Methode aufruft. Das System ruft onRestoreInstanceState () nur auf, wenn ein gespeicherter Status wiederhergestellt werden muss, sodass Sie nicht überprüfen müssen, ob das Bundle null ist

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
quelle
0

Grundsätzlich erhalten Sie mit onSaveInstanceState (Bundle outBundle) ein Bundle. Wenn Sie sich die Bundle-Klasse ansehen, werden Sie feststellen, dass Sie viele verschiedene Dinge darin ablegen können. Beim nächsten Aufruf von onCreate () erhalten Sie das Bundle nur als Argument zurück. Dann können Sie Ihre Werte erneut lesen und Ihre Aktivität wiederherstellen.

Nehmen wir an, Sie haben eine Aktivität mit einem EditText. Der Benutzer hat einen Text darin geschrieben. Danach ruft das System Ihren onSaveInstanceState () auf. Sie lesen den Text aus dem EditText und schreiben ihn über Bundle.putString ("edit_text_value", theValue) in das Bundle.

Jetzt heißt onCreate. Sie prüfen, ob das mitgelieferte Bundle nicht null ist. In diesem Fall können Sie Ihren Wert über Bundle.getString ("edit_text_value") wiederherstellen und wieder in Ihren EditText einfügen.


quelle
0

Dies dient der zusätzlichen Information.

Stellen Sie sich dieses Szenario vor

  1. ActivityA startet ActivityB.
  2. ActivityB startet eine neue ActivityAPrime von

    Intent intent = new Intent(getApplicationContext(), ActivityA.class);
    startActivity(intent);
  3. ActivityAPrime hat keine Beziehung zu ActivityA.
    In diesem Fall ist das Bundle in ActivityAPrime.onCreate () null.

Wenn ActivityA und ActivityAPrime dieselbe Aktivität anstelle unterschiedlicher Aktivitäten sein sollen, sollte ActivityB finish () aufrufen als startActivity ().

Ken
quelle
Nur um zu verdeutlichen, ist in Ihrem Beispiel ActivityA == ActivityA Instanz 1 und ActivityAPrime == ActivityA Instanz 2? Wenn Sie sagen: "ActivityB sollte finish () aufrufen als startActivity ()." Meinen Sie: (1) AcitivityB sollte finish () aufrufen und anschließend startActivity () verwenden (2) oder ActivityB sollte finish () aufrufen, anstatt überhaupt startActivity () zu verwenden? Wenn Sie Option 2 gemeint haben, wie würden Sie jemandem vorschlagen, dieselbe Aktivität zu starten? Eine Instanz1, damit Sie Daten der enthaltenen Aktivität laden können, bevor sie zerstört / beendet werden? Danke
cjayem13
ActivityA und ActivityAPrime gehören zur selben Klasse, aber zu unterschiedlichen Instanzen. In diesem Szenario hat ActivityA sein Geschäft noch nicht abgeschlossen. In der Mitte hat ActivityB ActivityB erstellt und gestartet. Wenn ActivityB beendet ist, sollte ActivityA sein verbleibendes Geschäft fortsetzen. In diesem Fall ist es falsch, startActivity aufzurufen und zu erwarten, dass ActivityA und ActiviyAPrime dieselbe Instanz sind. Wir sollten also ActivityA nicht neu starten, sondern ActivityB beenden und ActivityA seinen Betrieb wieder aufnehmen lassen ...
Ken
0

Wenn Daten nicht geladen werden savedInstanceStateVerwenden Sie den folgenden Code.
Das Problem ist, dass der URL-Aufruf nicht vollständig abgeschlossen werden kann. Überprüfen Sie daher, ob Daten geladen sind, und zeigen Sie den Wert instanceState an.

//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
quelle