Status unterschiedlicher Steuerelemente merken

jerevat

Mitglied
Hallo,

ich habe hier Spinner, Numberpicker und Checkboxen, deren Auswahl / Selektion ich bei App-Neustart beibehalten möchte.
Gibt es dafür Klassen, die das regulieren oder muss ich selber Daten als Textdatei am Gerät abspeichern und wieder aufrufen?
Außerdem, kennt Android sowas wie ein OnDestroy? Sollte es eigentlich geben, wenn es auch ein OnCreate gibt.
 

Robertop

Bekanntes Mitglied
Wenn ich mir so kleine Werte aus meiner App merken will, dann verwende ich normalerweise die SharedPreferences. Da kannst du jederzeit Key-Value Paare von den Werten ablegen, die du speichern willst, und diese dann beim Start einfach wieder auslesen.

Bei dem "onDestroy" ist die Frage, was genau du tun willst, und wann. Der Lifecycle einer App ist nicht so eindeutig, wie man im ersten Moment vermuten mag.
 

jerevat

Mitglied
Wenn ich mir so kleine Werte aus meiner App merken will, dann verwende ich normalerweise die SharedPreferences. Da kannst du jederzeit Key-Value Paare von den Werten ablegen, die du speichern willst, und diese dann beim Start einfach wieder auslesen.
Gesagt, getan:

Java:
private void saveSettings() {
    SharedPreferences sp = getSharedPreferences(getResources().getString(R.string.app_name), MODE_PRIVATE);
    SharedPreferences.Editor editor = sp.edit();

    editor.putBoolean("checkboxChecked", _checkBox.isChecked());
    editor.putInt("spinner1Index", _spinner1.getSelectedItemPosition());
    editor.putInt("spinner2Index", _spinner2.getSelectedItemPosition());
    //editor.putInt("spinner1Index", 1);
    //editor.putInt("spinner2Index", 4);
    editor.putInt("number", _numberPicker.getValue());
    editor.commit();

}

private void loadSettings() {
    SharedPreferences sp = getSharedPreferences(getResources().getString(R.string.app_name), MODE_PRIVATE);

    _checkBox.setChecked(sp.getBoolean("checkboxChecked", false));
    if (_checkBox.isChecked()) {
        _spinner1.setSelection(sp.getInt("spinner1Index", 0));
        _spinner2.setSelection(sp.getInt("spinner2Index", 0));
        _numberPicker.setValue(sp.getInt("number", 0));
    }
}

Ich hatte vor die Einstellungen im onDestroy() oder im onStop() zu speichern und sie im onCreate() aufzurufen:

Java:
@Override
protected void onStop() {
    saveSettings();    // entweder  hier speichern
    super.onStop();
    saveSettings();   // oder hier speichern
}

@Override
protected void onDestroy() {
    saveSettings();   // oder hier speichern
    super.onDestroy();
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ------ Initialisierungen und Listener --------
    loadSettings();   // hier die Einstellungen laden
}

Dort zu speichern, führte zu nichts. Es wurde nichts gespeichert und auch nichts geladen.
Dann nutzte ich den Checkbox-Klick zum Speichern, denn die Einstellungen sollen gespeichert und geladen werden, sofern die Checkbox selektiert ist:

Java:
// im onCreate(), vor loadSettings()
_checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
        saveSettings();
    }
});

Das führt nun dazu, dass die Checkbox-Selektion immer richtig abgespeichert und geladen wird, aber der Rest nicht.
Die Spinner-Indexe wollen nicht gespeichert werden bzw. nur, wenn sie hardgecodet sind, dann nehmen die Spinner beim Laden auch die hardgecodeten-gespeicherten Werte an.
Und der NumberPicker lässt sich nichts vorschreiben. Er verbleibt immer bei der Grundeinstellung (=0).

Was mach ich nur falsch?
 

Robertop

Bekanntes Mitglied
Sieht auf den ersten Blick jetzt eigentlich alles ok aus. Ich habe noch nicht so viel mit Spinnern gearbeitet, deswegen bin ich nicht sicher, ob du da die richtigen Funktionen verwendest. Kontrollier am besten mal, ob die Antwort von .getSelectedItemPosition() wirklich die richtige ist, um sie bei .setSelection() wieder zu setzen.

Wegen dem Speichern im onStop() und onDestroy(): Mir ist auch schon mal aufgefallen, dass Sachen nicht gespeichert werden, wenn man erst ganz am Schluss beim Beenden der Anwendung macht. Meine Vermutung ist, dass das Speichern nicht rechtzeitig fertig wird bevor die App abgeräumt ist. Aber eigentlich macht es aus meiner Sicht sowieso mehr Sinn, die Eingaben direkt zu speichern, wenn der Nutzer sie macht. Es ist ja auch möglich, dass ein Anruf oder sonst irgendwas den Benutzer unterbricht, und dann möchte man ja auch nicht, dass die Werte vergessen werden.
 

jerevat

Mitglied
Sieht auf den ersten Blick jetzt eigentlich alles ok aus. Ich habe noch nicht so viel mit Spinnern gearbeitet, deswegen bin ich nicht sicher, ob du da die richtigen Funktionen verwendest. Kontrollier am besten mal, ob die Antwort von .getSelectedItemPosition() wirklich die richtige ist, um sie bei .setSelection() wieder zu setzen.
Die Funktionen sind schon richtig gewählt. Wieso es nicht funktionierte, lag am Emulator hauptsächlich.
Um onStop() auszulösen, muss die App in den Hintergrund gelangen, was beim Emulator nie gemacht wurde bzw. die App wurde direkt beendet.
Am Gerät funktioniert das Speichern im onStop(). Im onDestroy passiert nachwievor nichts. Vielleicht muss man da einen Loop() einbauen.
 

Jw456

Top Contributor
OnPause() macht auch Sinn.
In anderen Programmiersprachen ist es üblich nur einen Destruktor zu haben und für so einen Fall dort die Einstellungen zu speichern, bevor die Anwendung alles freigibt.
Das hat nichts mit der Programmiersprache zu tun. Sondern mit dem Betriebssystem auf dem du arbeitst.
Für das du entwickellst.

Dir wurde doch auch ein Link zum Lifecycle einer Activity gegeben.
 

jerevat

Mitglied
Das hat nichts mit der Programmiersprache zu tun. Sondern mit dem Betriebssystem auf dem du arbeitst.
Für das du entwickellst.

Dir wurde doch auch ein Link zum Lifecycle einer Activity gegeben.
Der Lebenszyklus in Android-Apps liest sich interessant, aber dann sollte es zumindest auch so funktionieren wie beschrieben.
Was nutzt es einen onDestroy() zu haben, wenn dieser offensichtlich zu nichts taugt?
 

Jw456

Top Contributor
Dann lesen richtig wann das onDestroy ausgeführt wird. Nicht wenn die App in den Hindergrund geht.
Sondern zb wenn das System Speicher braucht oder du alle offnen Apps selber schließen willst. Sonnst nicht.
 

jerevat

Mitglied
Dann lesen richtig wann das onDestroy ausgeführt wird. Nicht wenn die App in den Hindergrund geht.
Sondern zb wenn das System Speicher braucht oder du alle offnen Apps selber schließen willst. Sonnst nicht.
Das habe ich auch nicht behauptet, sondern:
Die Funktionen sind schon richtig gewählt. Wieso es nicht funktionierte, lag am Emulator hauptsächlich.
Um onStop() auszulösen, muss die App in den Hintergrund gelangen, was beim Emulator nie gemacht wurde bzw. die App wurde direkt beendet.
Am Gerät funktioniert das Speichern im onStop(). Im onDestroy passiert nachwievor nichts. Vielleicht muss man da einen Loop() einbauen.
 

Robertop

Bekanntes Mitglied
Achso, verstehe. Du hast beim Emulator, um die App zu beenden, den Stopbutton der IDE verwendet, oder? Kann gut sein, dass die App dann einfach gestoppt wird, anstatt richtig "heruntergefahren" zu werden.

Ich würde das aber mal nachprüfen und auch beim Emulator die App auf dem richtigen Weg schließen. Dann sollte das eigentlich genauso funktionieren, wie bei einem richtigen Telefon.
 

jerevat

Mitglied
Achso, verstehe. Du hast beim Emulator, um die App zu beenden, den Stopbutton der IDE verwendet, oder? Kann gut sein, dass die App dann einfach gestoppt wird, anstatt richtig "heruntergefahren" zu werden.

Ich würde das aber mal nachprüfen und auch beim Emulator die App auf dem richtigen Weg schließen. Dann sollte das eigentlich genauso funktionieren, wie bei einem richtigen Telefon.
Anders herum. Im Emulator (Bluestacks) habe ich jedes Mal den Tab der App geschlossen und somit die App direkt beendet. Das bewirkte keinen Speichervorgang.
Am Endgerät habe ich die Stop-Taste benutzt, also das [ ] bzw. I I I. So wurde alles gespeichert.
 
Ähnliche Java Themen

Ähnliche Java Themen

Neue Themen


Oben