Dies ist ein klassisches Problem bei der Android-Entwicklung. Hier gibt es zwei Probleme:
- Es gibt einen subtilen Fehler im Android-Framework, der die Verwaltung des Anwendungsstapels während der Entwicklung erheblich erschwert, zumindest bei älteren Versionen (ich bin nicht ganz sicher, ob/wann/wie er behoben wurde). Ich werde diesen Fehler weiter unten besprechen.
- Der "normale" oder beabsichtigte Weg, dieses Problem zu lösen, ist mit der Dualität von onPause/onResume und onSaveInstanceState/onRestoreInstanceState ziemlich kompliziert
Wenn ich mir all diese Threads ansehe, vermute ich, dass die Entwickler häufig über diese beiden unterschiedlichen Themen gleichzeitig sprechen ... daher die ganze Verwirrung und die Berichte über "das funktioniert bei mir nicht".
Erstens, um das "beabsichtigte" Verhalten zu klären: onSaveInstance und onRestoreInstance sind anfällig und nur für den vorübergehenden Zustand. Die beabsichtigte Verwendung (soweit ich das beurteilen kann) besteht darin, die Wiederherstellung der Aktivität zu behandeln, wenn das Telefon gedreht wird (Änderung der Ausrichtung). Mit anderen Worten, die beabsichtigte Verwendung ist, wenn Ihre Aktivität logisch immer noch "oben" ist, aber dennoch vom System neu instanziiert werden muss. Das gespeicherte Bundle wird nicht außerhalb des Prozesses/Speichers/ GC Sie können sich also nicht wirklich darauf verlassen, wenn Ihre Aktivität in den Hintergrund tritt. Ja, vielleicht überlebt der Speicher Ihrer Aktivität den Wechsel in den Hintergrund und entgeht GC, aber das ist nicht zuverlässig (und auch nicht vorhersehbar).
Wenn Sie also ein Szenario haben, in dem es einen bedeutsamen "Benutzerfortschritt" oder einen Zustand gibt, der zwischen den "Starts" Ihrer Anwendung erhalten bleiben soll, ist die Anleitung, onPause und onResume zu verwenden. Sie müssen einen persistenten Speicher selbst auswählen und vorbereiten.
Aber - es gibt einen sehr verwirrenden Fehler, der all dies verkompliziert. Details sind hier:
Wenn Ihre Anwendung mit dem SingleTask-Flag gestartet wird und Sie sie später über den Startbildschirm oder das Startmenü starten, wird durch den anschließenden Aufruf eine NEUE Aufgabe erstellt ... Sie haben effektiv zwei verschiedene Instanzen Ihrer Anwendung, die denselben Stapel bewohnen ... was sehr schnell sehr seltsam wird. Dies scheint zu passieren, wenn Sie Ihre Anwendung während der Entwicklung starten (d.h. von Eclipse o IntelliJ ), so dass Entwickler häufig mit diesem Problem konfrontiert werden. Aber auch durch einige der Aktualisierungsmechanismen des App-Stores (so dass es sich auch auf Ihre Benutzer auswirkt).
Ich habe mich stundenlang durch diese Threads gekämpft, bevor ich erkannte, dass mein Hauptproblem dieser Fehler war und nicht das beabsichtigte Verhalten des Frameworks. Ein großartiger Bericht und Abhilfe (UPDATE: siehe unten) scheint von Benutzer @kaciula in dieser Antwort zu stammen:
Verhalten beim Drücken der Home-Taste
UPDATE Juni 2013 : Monate später habe ich endlich die "richtige" Lösung gefunden. Sie brauchen keine zustandsabhängigen StartApp-Flags selbst zu verwalten. Sie können dies vom Framework erkennen und entsprechend ausweichen. Ich verwende dies in der Nähe des Beginns meiner LauncherActivity.onCreate:
if (!isTaskRoot()) {
Intent intent = getIntent();
String action = intent.getAction();
if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && action != null && action.equals(Intent.ACTION_MAIN)) {
finish();
return;
}
}