Grundlegendes zur Android-Aktivität von launchMode: Standard, SingleTop, SingleTask und SingleInstance

Die Übersetzung des Artikels wurde speziell für fortgeschrittene Studenten in der Android-Entwicklung vorbereitet .




Aktivität ist eines der auffälligsten Konzepte in Android (das beliebteste mobile Betriebssystem mit einer gut gestalteten Speicherverwaltungsarchitektur, die Multitasking perfekt implementiert).

Auf die eine oder andere Weise ist mit dem Start von Activity auf dem Bildschirm nicht alles so einfach. Die Art und Weise, wie es ausgeführt wurde, ist ebenfalls wichtig. In diesem Thema gibt es viele Nuancen. Einer der wirklich wichtigen ist launchMode , über den wir in diesem Artikel sprechen werden.

Jede Aktivität wird erstellt, um mit unterschiedlichen Zielen zu arbeiten. Einige von ihnen sind so konzipiert, dass sie mit jeder Absicht separat funktionieren, z. B. Aktivitäten, die zum Erstellen von E-Mails im E-Mail-Client gesendet werden. Während andere als Singleton konzipiert sind, z. B. als Aktivitätspostfach.

Aus diesem Grund ist es wichtig anzugeben, ob Sie eine neue Aktivität erstellen oder eine vorhandene verwenden müssen, da dies sonst zu fehlerhafter UX oder Fehlern führen kann. Dank der Android-Kernel-Entwickler ist dies mit dem speziell dafür entwickelten launchMode ganz einfach .

LaunchMode-Definition


Im Wesentlichen können wir launchMode direkt als Tag-Attribut definieren <activity>in AndroidManifest.xml:

<activity
    android:name=".SingleTaskActivity"
    android:label="singleTask launchMode"
    android:launchMode="singleTask">

Es stehen 4 Arten von launchMode zur Verfügung. Schauen wir sie uns einzeln an.

Standard

Dies ist der Standardmodus.

Das Verhalten einer Aktivität, die auf diesen Modus eingestellt ist, erstellt immer eine neue Aktivität, die mit jeder gesendeten Absicht separat funktioniert. Wenn 10 Absichten zum Verfassen einer E-Mail gesendet wurden, müssen 10 Aktivitäten gestartet werden, um jede Absicht separat zu bedienen. Infolgedessen kann eine unbegrenzte Anzahl solcher Aktivitäten auf dem Gerät gestartet werden.

Verhalten unter Android vor Lollipop

Diese Art von Aktivität wird erstellt und in derselben Aufgabe, die die Absicht gesendet hat, oben auf dem Stapel platziert.



Das folgende Bild zeigt, was passiert, wenn wir das Bild mit der Standardaktivität teilen. Es wird in derselben Aufgabe wie oben beschrieben gestapelt, obwohl sie aus verschiedenen Anwendungen stammen.



Und das sehen Sie im Task-Manager. (Es mag etwas seltsam erscheinen.)



Wenn wir die Anwendung zu einer anderen Aufgabe wechseln und dann wieder zur Galerie wechseln, sehen wir immer noch, dass der Standard-Startmodus über der Galerie-Aufgabe platziert ist. Wenn wir also etwas in der Galerie tun müssen, müssen wir zuerst unsere Arbeit in dieser zusätzlichen Aktivität beenden.

Verhalten unter Android Lollipop

Wenn sich diese Aktivitäten auf dieselbe Anwendung beziehen, ist das Verhalten dasselbe wie in der Implementierung vor Lollipop - Platzieren auf dem Stapel über der Aufgabe.



Wenn die Absicht jedoch von einer anderen Anwendung gesendet wird, wird eine neue Aufgabe erstellt und die neu erstellte Aktivität als Stamm platziert, wie unten gezeigt.



Dies sehen Sie im Task-Manager.



Dies liegt daran, dass das Task-Management-System in Lollipop geändert wurde - es ist besser und verständlicher geworden. In Lollipop können Sie einfach zur Galerie zurückkehren, da es sich um eine andere Aufgabe handelt. Sie können eine andere Absicht senden. Es wird eine neue Aufgabe erstellt, die der Absicht auf die gleiche Weise wie die vorherige dient.



Ein Beispiel für diese Art von Aktivität ist das Verfassen von E-Mail-Aktivitäten oder die Statusposting-Aktivität des sozialen Netzwerks(Statusaktualisierung in sozialen Netzwerken). Wenn Sie eine Aktivität im Kopf haben, die jede Absicht separat verarbeitet, denken Sie an Standardaktivität .

singleTop


Der nächste Modus ist singleTop . Es verhält sich ähnlich wie Standard , was bedeutet, dass Sie so viele Instanzen von singleTop Activity erstellen können, wie wir möchten. Der einzige Unterschied besteht darin, dass, wenn sich bereits eine Aktivitätsinstanz mit demselben Typ oben im Stapel in der aufrufenden Aufgabe befindet, keine neue Aktivität erstellt wird. Stattdessen wird die Absicht über die Methode an die vorhandene Aktivitätsinstanz gesendet onNewIntent().



In singleTop - Modus müssen Sie die Handhabung der eingehenden Intent in berücksichtigen onCreate()und onNewIntent()so , dass es funktioniert in allen Fällen.

Ein Beispiel für die Verwendung dieses Modus ist die Suchfunktion. Lassen Sie uns ein Suchfeld erstellen, das Sie zu SearchActivity weiterleitet, um die Suchergebnisse anzuzeigen. Für eine bessere Benutzeroberfläche setzen wir normalerweise immer das Suchfeld auf die Suchergebnisseite, damit der Benutzer die nächste Suche durchführen kann, ohne zurück zu gehen.

Stellen Sie sich nun vor, wenn wir immer eine neue SearchActivity starten, um ein neues Suchergebnis bereitzustellen, erhalten wir 10 neue Aktivitäten für 10 Iterationen der Suche. Es wäre sehr seltsam, zurück zu gehen, da Sie zehnmal zurückklicken müssten, um alle Suchergebnisse durchzugehen und zur Stammaktivität zurückzukehren.

Wenn sich SearchActivity bereits oben im Stapel befindet, ist es am besten, eine Absicht an eine vorhandene Activity-Instanz zu senden und das Suchergebnis aktualisieren zu lassen. Jetzt befindet sich nur noch eine SearchActivity oben im Stapel, und Sie können einfach einmal auf die Schaltfläche "Zurück" klicken, um zur vorherigen Aktivität zurückzukehren. Das macht mehr Sinn.

In jedem Fall arbeitet singleTop in derselben Aufgabe wie der Anrufer. Wenn Sie erwarten, dass die Absicht an eine vorhandene Aktivität gesendet wird, die über eine andere Aufgabe gestellt wird, sollte ich Sie enttäuschen, indem ich sage, dass sie dort nicht mehr funktioniert. Wenn die Absicht von einer anderen Anwendung an singleTop Activity gesendet wird, wird die neue Aktivität unter dem gleichen Aspekt wie für den Standardstartmodus gestartet (Pre-Lollipop: Wird über die aufrufende Aufgabe gelegt, Lollipop: Es wird eine neue Aufgabe erstellt .

singleTask


Dieser Modus unterscheidet sich stark von Standard und SingleTop. Aktivitäten mit singleTask launchMode dürfen nur eine Instanz im System haben (ala singleton) . Wenn bereits eine Aktivitätsinstanz im System vorhanden ist, wird die gesamte Aufgabe, die die Instanz enthält, nach oben verschoben, und die Absicht wird über die Methode bereitgestellt onNewIntent(). Andernfalls wird eine neue Aktivität erstellt und in die entsprechende Aufgabe eingefügt.

Arbeiten in einer Anwendung

Wenn im System keine singleTask Activity-Instanz vorhanden war, wird eine neue erstellt und einfach in derselben Aufgabe auf dem Stapel abgelegt.



Wenn es jedoch vorhanden ist, werden alle Aktivitäten, die sich über dieser singleTask-Aktivität befinden, automatisch brutal zerstört (der Lebenszyklus ist abgeschlossen), um die gewünschte Aktivität oben auf dem Stapel anzuzeigen.Gleichzeitig wird Intent über eine wunderbare Methode an singleTask Activity gesendet onNewIntent().



Dies ist aus Sicht der Benutzererfahrung nicht sinnvoll, aber so gestaltet ...

Sie können eine Nuance feststellen, die in der Dokumentation erwähnt wird :

Das System erstellt eine neue Aufgabe und instanziiert eine Aktivitätsinstanz im Stammverzeichnis der neuen Aufgabe.

In der Praxis scheint dies jedoch nicht wie beschrieben zu funktionieren . Die SingleTask-Aktivität befindet sich weiterhin oben im Aktivitätsstapel der Aufgabe, wie aus dem Ergebnis des Befehls hervorgeht dumpsys activity.

Ta

sk id #239
  TaskRecord{428efe30 #239 A=com.thecheesefactory.lab.launchmode U=0 sz=2}
  Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.thecheesefactory.lab.launchmode/.StandardActivity }
    Hist #1: ActivityRecord{429a88d0 u0 com.thecheesefactory.lab.launchmode/.SingleTaskActivity t239}
      Intent { cmp=com.thecheesefactory.lab.launchmode/.SingleTaskActivity }
      ProcessRecord{42243130 18965:com.thecheesefactory.lab.launchmode/u0a123}
    Hist #0: ActivityRecord{425fec98 u0 com.thecheesefactory.lab.launchmode/.StandardActivity t239}
      Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.thecheesefactory.lab.launchmode/.StandardActivity }
      ProcessRecord{42243130 18965:com.thecheesefactory.lab.launchmode/u0a123}

Wenn sich die singleTask-Aktivität wie im Dokument beschrieben verhalten soll: Erstellen Sie eine neue Aufgabe und legen Sie die Aktivität als Stammaktivität fest. Sie müssen ein Attribut taskAffinityfür singleTask Activity wie folgt definieren.

<activity
    android:name=".SingleTaskActivity"
    android:label="singleTask launchMode"
    android:launchMode="singleTask"
    android:taskAffinity="">

Das wird das Ergebnis sein, wenn wir versuchen zu rennen SingleTaskActivity.





Ihre Aufgabe ist es, taskAffinityabhängig vom gewünschten Verhalten der Aktivität zu entscheiden, ob Sie sie verwenden möchten oder nicht.

Interaktion mit einer anderen Anwendung

Sobald die Absicht von einer anderen Anwendung gesendet wurde und keine Instanzen von Aktivitäten im System erstellt wurden, wird eine neue Aufgabe mit einer neuen Aktivität erstellt, die als Stammaktivität platziert wird.





Wenn es keine Aufgabe gibt, die Eigentümer der aufrufenden singleTask-Aktivität wäre, wird stattdessen eine neue Aktivität angezeigt.



Wenn in einer Aufgabe eine Instanz einer Aktivität vorhanden ist, wird die gesamte Aufgabe nach oben verschoben, und für jede einzelne Aktivität, die sich über einer einzelnen Aufgabenaktivität befindet, wird der Lebenszyklus abgeschlossen. Wenn die Zurück-Taste gedrückt wird, muss der Benutzer die Aktivität auf dem Stapel durchlaufen, bevor er zur aufrufenden Aufgabe zurückkehrt.



Ein Beispiel für die Verwendung dieses Modus ist eine beliebige Einstiegspunktaktivität, z. B. die Seite "Posteingang" eines E-Mail-Clients oder eine Zeitleiste für soziale Netzwerke. Diese Aktivitäten setzen nicht mehr als eine Instanz voraus, sodass singleTask seine Aufgabe perfekt erfüllt. In jedem Fall sollten Sie diesen Modus mit Bedacht verwenden, da in diesem Modus Aktivitäten wie oben beschrieben ohne Bestätigung des Benutzers zerstört werden können.

singleInstance


Dieser Modus ist singleTask sehr ähnlich, bei dem nur eine Instanz einer Aktivität auf einem System vorhanden sein kann. Der Unterschied besteht darin, dass eine Aufgabe mit dieser Aktivität nur eine Aktivität haben kann - eine mit einem singleInstance-Attribut . Wenn eine andere Aktivität von dieser Art von Aktivität aufgerufen wird, wird automatisch eine neue Aufgabe erstellt, um diese neue Aktivität aufzunehmen. Wenn eine einzelne Instanzaktivität aufgerufen wird, wird eine neue Aufgabe erstellt, um diese Aktivität zu hosten.

In jedem Fall ist das Ergebnis ziemlich seltsam. Aus den bereitgestellten InformationendumpsysEs ist klar, dass es zwei Aufgaben im System gibt, aber nur eine wird im Aufgabenmanager angezeigt, je nachdem, welche oben liegt. Obwohl eine Aufgabe noch im Hintergrund ausgeführt wird, können wir sie daher nicht wieder in den Vordergrund schalten. Es macht überhaupt keinen Sinn.

Dies ist der Fall, wenn eine singleInstance-Aktivität aufgerufen wird, während bereits eine Aktivität auf dem Stapel vorhanden ist.



Und hier ist, was wir im Task-Manager sehen.



Da diese Aufgabe nur eine Aktivität haben kann, können wir nicht mehr zu Aufgabe Nr. 1 zurückkehren. Die einzige Möglichkeit, dies zu tun, besteht darin, die Anwendung über den Starter neu zu starten. Infolgedessen wird die singleInstance-Aufgabe im Hintergrund ausgeblendet.

Auf jeden Fall gibt es einige Problemumgehungen für dieses Problem. Weisen Sie singleInstance Activity wie bei singleTask Activity einfach ein Attribut taskAffinityzu, sodass im Task-Manager mehrere Aufgaben vorhanden sein können.

<activity
    android:name=".SingleInstanceActivity"
    android:label="singleInstance launchMode"
    android:launchMode="singleInstance"
    android:taskAffinity="">

Jetzt macht das Bild mehr Sinn.



Dieser Modus wird selten verwendet. Einige der praktischen Anwendungsfälle sind ein Aktivitätsstarter oder eine Anwendung, für die Sie zu 100% sicher sind, dass es nur eine Aktivität geben sollte. In jedem Fall empfehle ich Ihnen, diesen Modus nicht zu verwenden, es sei denn, es liegt ein Notfall vor.

Absichtsflaggen


Zusätzlich AndroidManifest.xmlzum direkten Einstellen des Startmodus können wir das Verhalten auch mit einem Tool namens Intent Flags anpassen , zum Beispiel:

Intent intent = new Intent(StandardActivity.this, StandardActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);

wird StandardActivitymit der Bedingung singleTop launchMode gestartet.

Es gibt einige Flags, mit denen Sie arbeiten können. Weitere Informationen hierzu finden Sie hier .

Ich hoffe, Sie fanden diesen Artikel nützlich =)

Erfahren Sie mehr über den Kurs

All Articles