Die Absicht wurde nicht richtig wiederhergestellt, nachdem die Aktivität beendet wurde, wenn die oberen und die unteren Flags eindeutig angegeben wurden

8

In meiner Anwendung wurde eine Aktivität mit dem FLAG_ACTIVITY_SINGLE_TOP und FLAG_ACTIVITY_CLEAR_TOP Flags, weil ich sicherstellen möchte, dass nur eine Instanz dieser Aktivität an der Spitze der Stack und alle Aktivitäten oberhalb der alten Instanz sind geschlossen. So weit so gut.

Als nächstes wollte ich testen, ob die Aktivität korrekt wiederhergestellt wird, nachdem sie mehr als einmal erstellt und anschließend zerstört wurde. Ich achte darauf, die Absicht manuell festzulegen, indem ich Activity.setIntent() wenn Activity.onNewIntent() so aufgerufen wird Die letzte Absicht wird von Activity.getIntent() zurückgegeben. Um das zu testen, habe ich die Option "Aktivitäten nicht beibehalten" in den Entwickleroptionen aktiviert, aber die von Activity.getIntent() Wenn die Aktivität neu erstellt wird, ist dies 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 etwas falsch verstanden?

    
futtetennista 13.02.2013, 12:13
quelle

2 Antworten

17

Wenn Sie Ihre App beenden, während sie im Vordergrund ist, ist das nicht dasselbe wie wenn Android Ihre App tötet (was nur geschieht, wenn Ihre App im Hintergrund läuft). 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 nach dem Beenden und Neustarten der App die Bundle , die an onCreate() übergeben wird, null ist.

Leider ist es ziemlich schwierig zu simulieren, was passiert, wenn Android deine App tötet.

BEARBEITEN: Nach dem Kommentar von OP wurde mehr hinzugefügt

Hier ist ein konkretes Beispiel für Diskussionszwecke. Zuerst ohne die Entwickleroption "Aktivitäten nicht beibehalten":

  • ActivityA ist die Root-Aktivität
  • Wir starten ActivityA
  • ActivityA.onCreate() heißt
  • ActivityA startet jetzt ActivityB
  • ActivityB.onCreate() wird aufgerufen (Der Aktivitätsstapel enthält jetzt ActivityA - & gt; ActivityB )
  • ActivityB startet ActivityA mit FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP und ein zusätzliches "foo"
  • ActivityA.onNewIntent() wird mit Intent mit FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP und einem zusätzlichen "foo"
  • aufgerufen
  • ActivityB.onDestroy() wird aufgerufen, da der Aktivitätsstapel wieder auf ActivityA zurückgesetzt wurde

Nun, lassen Sie uns genau dasselbe tun, aber aktivieren Sie die Entwickleroption "Aktivitäten nicht beibehalten" (Ich habe in fett die Dinge hervorgehoben, die sich vom vorherigen Szenario unterscheiden):

  • ActivityA ist die Root-Aktivität
  • Wir starten ActivityA
  • ActivityA.onCreate() heißt
  • ActivityA startet jetzt ActivityB
  • ActivityB.onCreate() wird aufgerufen (Der Aktivitätsstapel enthält jetzt ActivityA - & gt; ActivityB )
  • Da ActivityA gestoppt wurde, zerstört Android es und ruft ActivityA.onDestroy()
  • auf
  • Hinweis: Der Aktivitätsstapel enthält weiterhin ActivityA - & gt; ActivityB , obwohl momentan keine Instanz von ActivityA vorhanden ist. Android merkt sich den ganzen Status
  • ActivityB startet ActivityA mit FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP und ein zusätzliches "foo"
  • Da Android keine Instanz von ActivityA hat, um es zu reaktivieren, muss es eine erstellen, also tut es das und dann ...
  • ActivityA.onCreate() wird mit demselben Intent aufgerufen, mit dem es aufgerufen wurde, als die ursprüngliche Instanz von ActivityA erstellt wurde (dh: LAUNCH intent ohne Flags und ohne Extras)
  • ActivityA.onNewIntent() wird mit Intent mit FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP und einem zusätzlichen "foo"
  • aufgerufen
  • ActivityB.onDestroy() wird aufgerufen, da der Aktivitätsstapel wieder auf ActivityA zurückgesetzt wurde

Wichtig ist hier, dass Android immer onCreate() aufruft, wenn es eine Aktivitätsinstanz erstellt. Stellen Sie sich das wie den Konstruktor eines Activity vor. 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() .

Wenn Sie setIntent() aufrufen, ändert dies nicht die Intent , die Android speichert und wiederherstellt. Dies ändert nur den speicherinternen Intent , der von einem Aufruf an getIntent() zurückgegeben wird.

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

    
David Wasser 13.02.2013 12:38
quelle
3

Nicht sicher, ob Sie eine Lösung dafür gefunden haben oder nicht, aber die onNewIntent-Methode (Intent theNewIntent) für die Zielaktivität & amp; Aufruf von SetIntent (theNewIntent) löste es für mich.

%Vor%     
Ryan 19.08.2013 06:09
quelle

Tags und Links