2013-02-13 9 views
8

sind. In meiner Anwendung wurde eine Aktivität mit den Flags FLAG_ACTIVITY_SINGLE_TOP und FLAG_ACTIVITY_CLEAR_TOP gestartet, da ich sicherstellen möchte, dass nur eine Instanz dieser Aktivität aktiv ist oben auf dem Stapel und alle Aktivitäten über der alten Instanz sind geschlossen. So weit, ist es gut.Absicht wurde nicht korrekt wiederhergestellt, nachdem die Aktivität beendet wurde, wenn die oberen und unteren Flags

Als nächstes wollte ich testen, ob die Aktivität korrekt wiederhergestellt wird, nachdem sie mehr als einmal erstellt und nacheinander zerstört wurde. Ich achte darauf, die Absicht unter Verwendung von Activity.setIntent() manuell festzulegen, wenn Activity.onNewIntent() aufgerufen wird, sodass die letzte Absicht von Activity.getIntent() zurückgegeben wird. Um zu testen, habe ich die Option "Aktivitäten nicht beibehalten" in den Entwickleroptionen aktiviert, aber die Absicht, die von Activity.getIntent() zurückgegeben wird, wenn die Aktivität neu erstellt wird, ist die allererste Absicht, die sie erstellt hat und nicht die neueste.

Dies passiert auf JB und ICS, ich habe es nicht auf älteren Versionen getestet. Mache ich etwas falsch oder habe ich in den Dokumenten etwas falsch verstanden?

Antwort

16

Wenn Sie Ihre App beenden, während sie im Vordergrund ist, ist dies nicht dasselbe wie wenn Android Ihre App tötet (was nur geschieht, wenn Ihre App im Hintergrund ist). Wenn du die App startest und dann neu startest, ist es, als würde alles von vorne beginnen. Es gibt keine "Wiederherstellung" hier. Wenn Sie die Protokollierung zu onCreate() hinzufügen, sollten Sie sehen, dass Bundle, die an onCreate() übergeben wird, null ist, nachdem Sie Ihre Anwendung beenden und wenn starten.

Leider ist es ziemlich schwierig zu simulieren, was passiert, wenn Android deine App umbringt.

EDIT: mehr Material nach OP Kommentar hinzugefügt

Hier ist ein konkretes Beispiel zu Diskussionszwecken.Erste ohne der Entwickler Option "Do Aktivitäten nicht halten":

  • ActivityA ist die Aktivität Wurzel
  • Wir ActivityA
  • ActivityA.onCreate() genannt wird
  • startet
  • ActivityA nun ActivityB
  • ActivityB.onCreate() ist aufgerufen (Der Aktivitätsstack enthält jetzt ActivityA ->ActivityB)
  • ActivityB beginnt ActivityA mit FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP und ein extra "foo"
  • ActivityA.onNewIntent() wird mit der Intent enthält FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP und eine zusätzliche "foo"
  • ActivityB.onDestroy() genannt wird, da die Aktivität Stapel wurde zurück
zu ActivityA gelöscht genannt

Jetzt machen wir genau dasselbe, aber aktivieren Sie die Entwickler-Option "Aktivitäten nicht behalten" (Ich habe in fett markiert die Sachen, die sich vom vorherigen Szenario unterscheiden) :

  • ActivityA die Aktivität Wurzel ist
  • Wir ActivityA
  • ActivityA.onCreate() genannt wird
  • ActivityA jetzt beginnt ActivityB
  • ActivityB.onCreate() genannt wird (Der Aktivitätsstapel enthält jetzt ActivityA ->ActivityB) starten
  • Weil ActivityA gestoppt hat, zerstört Android es und ruft ActivityA.onDestroy()
  • Hinweis: Die Aktivität Stapel enthält noch ActivityA ->ActivityB, obwohl es keine Instanz von ActivityA im Moment ist. Android erinnert sich an all den Staat
  • ActivityB beginnt ActivityA mit FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP und ein extra „foo“
  • Da Android keine Instanz von ActivityA zu reaktivieren hat, es erstellen muss, so dass es funktioniert und dann ...
  • ActivityA.onCreate() wird mit dem gleichen Intent genannt, dass es mit, wenn die ursprüngliche Instanz von ActivityA wurde erstellt (dh: LAUNCH Absicht ohne Fahnen und keine Extras) genannt wurde
  • ActivityA.onNewIntent() wird mit der Intent enthält FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP genannt und ein extra "foo"
  • ActivityB.onDestroy() wird, da die Aktivität Stapel zurückgerufen ActivityA

gelöscht wurde Beachten Sie, dass Android immer onCreate() aufruft, wenn eine Aktivitätsinstanz erstellt wird. Denken Sie daran wie der Konstruktor eines Activity. Wenn Android eine Instanz von Activity neu erstellen muss, weil der Prozess beendet wurde oder die Aktivität zerstört wurde, wird ein neues Objekt instanziiert, dann onCreate() aufgerufen und dann (falls erforderlich) onNewIntent() aufgerufen. Wenn Sie setIntent() anrufen, ändert das nicht wirklich die Intent, die Android speichert und wiederherstellt. Dies ändert nur den speicherinternen Intent, der von einem Anruf an getIntent() zurückgegeben wird.

Ich hoffe, das ist jetzt klarer. Wenn nicht, lass es mich wissen.

+0

Ich habe nicht beschrieben, wie die Aktivität korrekt beendet wird. Ich habe gerade meine Frage bearbeitet. – futtetennista

+0

Ich habe meine Antwort bearbeitet, um sie genauer zu erklären. –

+1

Ich finde Ihre letzte Aussage - das ist völlig richtig, das ist, was Android tut - ein bisschen verwirrend. Warum sollte das Framework die erste Absicht speichern und nicht die letzte? Wenn ich diese Flags hinzufüge, möchte ich typischerweise ActivityA einen anderen Inhalt anzeigen lassen. Aber wenn es getötet und dann mit der ersten Absicht wiederhergestellt wird, sehe ich alte Inhalte. Eine Änderung an dem, was Sie geschrieben haben: Nachdem Sie Ihre App beendet und neu gestartet haben, ist das Bundle, das an 'onCreate()' übergeben wird, nicht null, wenn Sie etwas auf 'onSavedInstanceState()' gespeichert haben. – futtetennista

2

Nicht sicher, ob Sie eine Lösung für dieses oder nicht gefunden haben, sondern auch für die Zielaktivität der onNewIntent (Intent theNewIntent) Methode überschrieben & Aufruf setIntent (theNewIntent) gelöst es für mich.

@Override 
protected void onNewIntent(Intent intent) { 
    super.onNewIntent(intent); 

    /* 
    * This overrides the original intent. 
    */  
    setIntent(intent); 
} 
Verwandte Themen