Was sind die Unterschiede zwischen FLAG_ACTIVITY_RESET_TASK_IF_NEEDED und FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP?

Ich bin dabei, endlich das Kapitel über die Aufgaben für mein Buch zu schreiben, und ich begegne ein paar anhaltende Rätsel.

Dinge, die als Home-Screen-Lader dienen, scheinen die Kombination von FLAG_ACTIVITY_NEW_TASK und FLAG_ACTIVITY_RESET_TASK_IF_NEEDED wenn sie die angeforderte Launcher-Aktivität starten:

  • E-Mail-Client über Intent öffnen (aber keine Nachricht senden)
  • Wie kann ich die neue Absicht in onNewIntent () erfassen?
  • Wie man eine Aktivität in Android mit Absicht zu stoppen?
  • USER_PRESENT Absicht für GO Locker
  • Übergeben von Werten durch Bündel und erhalten ihren Wert auf eine andere Aktivität
  • Erkennung, wenn ein USB-Gerät auf Android losgelassen wird
  •  Intent i=new Intent(Intent.ACTION_MAIN); i.addCategory(Intent.CATEGORY_LAUNCHER); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); i.setComponent(name); startActivity(i); 

    Die Dokumentation für FLAG_ACTIVITY_RESET_TASK_IF_NEEDED hat:

    Wenn gesetzt, und diese Aktivität wird entweder in einer neuen Aufgabe gestartet oder bringt eine bestehende Aufgabe an die Spitze, dann wird es als die Haustür der Aufgabe gestartet werden. Dies führt zu der Anwendung aller Affinitäten, die erforderlich sind, um diese Aufgabe im richtigen Zustand zu haben (entweder bewegte Aktivitäten zu oder von ihr) oder einfach diese Aufgabe in ihren Ausgangszustand zurücksetzen, wenn nötig.

    Das ist nicht besonders klar

    Insbesondere scheint es, dass die gleichen Effekte mit einer Kombination von FLAG_ACTIVITY_CLEAR_TOP und FLAG_ACTIVITY_SINGLE_TOP zu sehen FLAG_ACTIVITY_SINGLE_TOP . Zitieren der docs für FLAG_ACTIVITY_CLEAR_TOP :

    Wenn gesetzt, und die Aktivität, die gestartet wird, bereits in der aktuellen Aufgabe ausgeführt wird, dann statt der Einführung einer neuen Instanz dieser Aktivität, werden alle anderen Aktivitäten oben auf sie geschlossen und diese Absicht wird an die (jetzt auf Top) alte Aktivität als neue Absicht …

    Die aktuell laufende Instanz von [die gewünschte Aktivität] wird entweder die neue Absicht erhalten, die ihr hier in ihrer onNewIntent () – Methode startet oder selbst beendet und mit der neuen Absicht neu gestartet wird. Wenn es seinen Startmodus als "multiple" (die Standardeinstellung) deklariert hat und du FLAG_ACTIVITY_SINGLE_TOP nicht in der gleichen Absicht gesetzt hast, dann wird es fertig und neu erstellt; Für alle anderen Start-Modi oder wenn FLAG_ACTIVITY_SINGLE_TOP gesetzt ist, wird diese Absicht an die aktuelle Instanz onNewIntent () ausgeliefert.

    Die Dokumentation von FLAG_ACTIVITY_CLEAR_TOP macht zumindest für mich Sinn.

    Also, was macht FLAG_ACTIVITY_RESET_TASK_IF_NEEDED das anders als die Kombination von FLAG_ACTIVITY_CLEAR_TOP und FLAG_ACTIVITY_SINGLE_TOP ?


    Bonuspunkte, wenn Sie erklären können, was FLAG_ACTIVITY_CLEAR_TASK tut, das sich von einer der beiden anderen oben beschriebenen Optionen unterscheidet.

    Wenn in einer Absicht, die an Context.startActivity () übergeben wird, gesetzt wird, führt dieses Flag zu einer vorhandenen Aufgabe, die mit der Aktivität verbunden werden soll, die gelöscht werden soll, bevor die Aktivität gestartet wird. Das heißt, die Aktivität wird die neue Wurzel einer ansonsten leeren Aufgabe, und alle alten Aktivitäten sind beendet. Dies kann nur in Verbindung mit FLAG_ACTIVITY_NEW_TASK verwendet werden.

    Ein offensichtlicher Unterschied zwischen diesem und FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP ist, dass FLAG_ACTIVITY_CLEAR_TASK benötigt. Aber anders als das scheint es, als ob die Netto-Effekte gleich sind und auch mit FLAG_ACTIVITY_RESET_TASK_IF_NEEDED .

  • Warum schließt ausschließenFromRecents alle Aktivitäten entfernen?
  • Welche Absicht für Einstellungen - Datenverwendung
  • Wie kann man das Bild in Google Plus über eine Android-App teilen?
  • Übertragen von Daten von einer Aktivität zu einer anderen Aktivität mit Intents
  • Android: Event ACTION_POWER_CONNECTED wird nicht an meinen BroadcastReceiver gesendet
  • Android-Host-Intent-Filter auf einem Platzhalter
  • 3 Solutions collect form web for “Was sind die Unterschiede zwischen FLAG_ACTIVITY_RESET_TASK_IF_NEEDED und FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP?”

    Ich hatte einen Blick auf den Quellcode für den ActivityManager . Die Fahne Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED macht tatsächlich eine Magie, die Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP nicht: Es löst Task reparenting aus .

    Hier ist ein (wenn auch lahm) Beispiel:

    In App A haben wir die root Activity RootA und wir haben eine andere Aktivität ReparentableA :

     <application android:label="@string/app_name"> <activity android:name=".RootA"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:name=".ReparentableA" android:allowTaskReparenting="true"/> </application> 

    App A hat den Paketnamen "com.app.a", so dass die Standard- taskAffinity seiner Komponenten "com.app.a" ist.

    In App B haben wir die Wurzel Aktivität RootB :

     <application android:label="@string/app_name"> <activity android:name="RootB"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> 

    App B hat den Paketnamen "com.app.b", so dass die Standard- taskAffinity seiner Komponenten "com.app.b" ist.

    Jetzt starten wir App B aus dem HOME-Bildschirm. Dies startet eine neue Aufgabe und erstellt eine neue Instanz von Activity RootB als root Activity in dieser Task. Aktivität RootB startet jetzt die Aktivität ReparentableA in der Standardart, ohne spezielle Flaggen. Eine Instanz von ReparentableA wird erstellt und in der aktuellen Aufgabe auf RootB .

    Drücken Sie HOME.

    Jetzt starten wir App A aus dem HOME-Bildschirm. Dies startet eine neue Aufgabe und erstellt eine neue Instanz von Activity RootA als root Activity in dieser Task. HINWEIS: Wenn Android einen "Launcher" Intent startet, setzt er automatisch die Flags Intent.FLAG_ACTIVITY_NEW_TASK und Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED . Aus diesem RootA löst das Starten von RootA jetzt die Aufgabe wieder auf. Android sieht, um zu sehen, ob es irgendwelche Aktivitäten in irgendwelchen anderen Aufgaben gibt, die eine Affinität für diese neue Aufgabe haben (und sind reparentable). Es findet ReparentableA (das die gleiche Aufgabenaffinität wie RootA ) in der App B-Task und verschiebt es in die neue App A-Task. Beim Start von App A sehen wir nicht RootA , wir sehen tatsächlich ReparentableA , da es an die Spitze der neuen Aufgabe verschoben wird.

    Wenn wir zu App B zurückkehren, können wir sehen, dass ReparentableA aus dem RootB verschwunden ist und diese Aufgabe nun nur aus einer Aktivität: RootB .


    Hinweise zur Verwendung von Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP

    Die wichtige Sache, sich daran zu erinnern, diese Flags zu verwenden, um "eine Aufgabe zurückzusetzen" ist, dass es nur funktioniert, wenn es bereits eine Instanz des Ziels Aktivität an der Wurzel der Aufgabe gibt . Wenn deine Root-Aktivität jemals beendet ist, kannst du deine Aufgabe nicht löschen, indem du die root-Aktivität mit Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP . Android wird nur eine neue Instanz des Ziels (root) Aktivität erstellen und legen Sie es auf die vorhandenen Aktivitäten in der Aufgabe , die wahrscheinlich gar nicht, was Sie wollen.


    Unterschied zwischen Intent.FLAG_ACTIVITY_CLEAR_TASK und Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP :

    Wie oben erwähnt, mit CLEAR_TOP | SINGLE_TOP CLEAR_TOP | SINGLE_TOP funktioniert nur, wenn bereits eine Instanz des Ziels Aktivität in der Task vorhanden ist. CLEAR_TASK entfernt jedoch alle Aktivitäten aus der Task, unabhängig davon, ob es eine Instanz des Ziels Aktivität in der Task gab oder nicht. Auch die Verwendung von CLEAR_TASK stellt sicher, dass die CLEAR_TASK die CLEAR_TASK der Aufgabe wird, ohne dass Sie wissen müssen, welche Aktivität die Root-Aktivität war, bevor Sie die Aufgabe gelöscht haben.


    Unterschied zwischen Intent.FLAG_ACTIVITY_CLEAR_TASK und Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED :

    Wie oben erwähnt, wird mit CLEAR_TASK immer alle Aktivitäten aus der Aufgabe entfernt und eine neue Instanz der CLEAR_TASK gestartet. Im Gegensatz dazu setzt RESET_TASK_IF_NEEDED nur die Aufgabe in bestimmten Situationen zurück (der "IF_NEEDED" -Teil). Die Aufgabe ist nur "Reset", wenn Android entweder:

    • Erstellen einer neuen Aufgabe (in diesem Fall beinhaltet die "Reset" -Funktionalität die oben beschriebene Aufgabenreparierung) oder
    • Wenn Android eine Hintergrundaufgabe in den Vordergrund bringt (in diesem Fall wird die Aufgabe nur von Aktivitäten abgelöst, die mit Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET gestartet Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET und alle Aktivitäten, die oben auf diesen Aktivitäten stehen). HINWEIS: Die Wurzel Aktivität wird in diesem Fall nie gelöscht.

    WICHTIGER HINWEIS: Wenn Sie testen, beachten Sie bitte, dass es einen Unterschied in der Art, wie Android verhält sich beim Start von Apps aus dem HOME-Bildschirm (oder aus der Liste der verfügbaren Anwendungen) und bei der Auswahl von Aufgaben aus der aktuellen Task-Liste.

    Im ersten Fall (Starten einer App, indem man sie aus der Liste der verfügbaren Anwendungen oder aus einer Verknüpfung auf dem HOME-Bildschirm Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED ), ein Launcher Intent mit Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED wird erstellt. Dies wird unabhängig davon verwendet, ob die App bereits läuft. Die Intent wird gestartet und dann gibt der ActivityManager heraus, was zu tun ist.

    Im zweiten Fall (Auswahl einer Aufgabe aus der Liste der letzten Aufgaben), wenn die Aufgabe noch existiert, ist es nur die Front gebracht. Die Aufgabe "Reset" wird NICHT ausgegeben, wenn die Aufgabe mit der aktuellen Taskliste nur nach vorne gebracht wird. Es ist mir nicht klar, wie das verwaltet wird und ich habe keine Chance gehabt, durch den Quellcode zu schauen, um herauszufinden, warum das so ist.


    Ich hoffe, das beantwortet Ihre Fragen. Wir freuen uns auf Feedback und Testergebnisse.

    Ich könnte mich hier irren, aber in meinem Verständnis FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED analysiert alle Tasks und stellt sicher, dass nur eine Task mit Launcher-Aktivität läuft.

    FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP wird nur die aktuelle Aufgabe untersuchen, also könntest du mit 2 Launcher-Instanzen gleichzeitig laufen (wenn die erste als separate Aufgabe erstellt wurde).

    1) FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

    Wenn eine Aufgabe ansteht, wird sie diesen Prozess zerstören und die von Ihnen angeforderte Aktivität starten

    2) FLAG_ACTIVITY_CLEAR_TOP

    Wenn eine vorherige Absicht dieser Aktivität ausgeführt wird, wird diese Methode die laufende Instanz der Aktivität ausführen, alle anderen Aktivitäten schließen und die Aktivität mit der vorherigen Instanz starten.

    3) FLAG_ACTIVITY_SINGLE_TOP

    Wenn vor kurzem diese Aktivität gestartet wurde und die Instanz gespeichert wird, wird sie diese Aktivität nicht starten.

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.