Animovaný tahák režimu spouštění systému Android

20. prosince, 2018 – 6 minut čtení

Před API 11 jsme používali aktivity zobrazující každou novou stránku na obrazovce. Nyní je díky fragmentům a navigačním nástrojům v rozhraní API 28 zcela možné vytvořit velmi komplexní aplikaci s jedinou aktivitou. Aktivity jsou však stále skvělé pro rozdělení aplikace na etapy a procesy. Možná chcete rozdělit celý marketing do jedné aktivity a vlastní aplikaci mít ve vlastní aktivitě. Možná chcete mít jednu sekci vyhrazenou pro nějakou funkci, například službu chatu. Znalost režimů spouštění aktivit vám pomůže lépe rozdělit tyto procesy tak, aby dávaly uživatelům smysl. Když jsem seděl v práci, nikdy jsem si nemohl z hlavy vzpomenout na režimy spouštění, tak jsem si řekl, že o tom napíšu blog, naanimuju pár gifů pro ilustraci pojmů a pak se o to se všemi podělím. Užijte si to!“

Než začneme mluvit o režimech spouštění, pojďme nejprve pochopit roli úlohy. Úloha obsahuje kolekci činností, které jsou uspořádány v zásobníku zvaném backstack. První aktivita, která se v úloze spouští, je kořenová aktivita. Stisknutím tlačítka zpět na kořenové aktivitě dojde nejen ke zničení aktivity, ale také ke zničení úlohy a případně i celé aplikace.

Nyní se ponoříme do některých režimů spouštění!

Řekněme, že máte úlohu s kořenovou aktivitou nazvanou Aktivita A a poté spustíte novou aktivitu nazvanou B, B se posune na vrchol zásobníku. Nyní řekněme, že z právě vytvořené aktivity B spustíte další aktivitu B, nyní budete mít dvě instance aktivity B naskládané nad sebou. Pokud uživatel stiskne tlačítko zpět, vrátí se do jiné instance aktivity B. To by mohlo být pro uživatele velmi matoucí. Stohování a vytváření aktivit nad sebou, bez ohledu na to, co se děje, se nazývá standardní režim spouštění. Pokud není v manifestu aktivity XML definován žádný režim spouštění, aktivita použije standardní režim spouštění.

Když nyní vidíme, jak může být standardní režim pro uživatele matoucí, můžeme nyní pochopit režim spouštění Single Top. Tento režim spouštění zabraňuje tomu, aby se různé instance stejných činností skládaly na sebe. Řekněme, že aktivita B je single top. Režimy spouštění můžeme v manifestu definovat takto:

///AndroidManifest.xml
<application
...>
<activity android:name=".Activity_A">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <activity android:name=".Activity_B" android:launchMode="singleTop"/> <activity android:name=".Activity_C"/>
<activity android:name=".Activity_D"/>
</application>

Pokud tedy nyní spustíte aktivitu B z aktivity B, místo aby se vytvořila nová instance aktivity B a naskládala se na starou aktivitu B, záměr se předá do aktuální instance aktivity B. Jediný způsob, jak mít v jedné úloze dvě instance stejné aktivity, je spustit z aktivity B jinou aktivitu a pak z ní vytvořit aktivitu B. V případě, že se aktivita B spustí z aktivity B, záměr se předá do aktuální instance aktivity B. V případě, že se aktivita B spustí z aktivity B, záměr se předá do aktuální instance aktivity B. Hlavním konceptem režimu spuštění single top je, že nemůžete mít dvě instance téže aktivity naskládané na sobě.

Pokud nechcete mít v úloze 2 instance téže aktivity single top při použití režimu spuštění single top, můžete v záměru předat konstantu FLAG_ACTIVITY_CLEAR_TOP. Pro ilustraci, co to dělá, řekněme, že váš zásobník aktivit je ABC (B je stále single top). Pokud spustíte B z C pomocí FLAG_ACTIVITY_CLEAR_TOP, váš zásobník vyskočí až na B a záměr bude předán právě této instanci B.

// code example for passing the constant flag in your intentIntent intent = new Intent(this, Activity_B.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Další režim spouštění se nazývá Single Task. V tomto režimu spouštění uvádíme, že aktivita může patřit pouze k jedné úloze v rámci všech úloh v aplikaci. Takže podobně jako v případě chování FLAG_ACTIVITY_CLEAR_TOP, pokud je váš zásobník ABC a z C spustíte B (jedinou úlohu), vyskočíme až na B a předáme záměr této instanci.

<activity android:name=".Activity_B" android:launchMode="singleTask"/>

Ale co když chceme, aby B byla ve vlastní úloze? Zde přichází na řadu příbuznost úloh. Příbuznost úloh umožňuje definovat, do které úlohy daná činnost patří. Ve výchozím nastavení má aktivita stejnou afinitu k úloze jako její kořenová aktivita. Pomocí afinity úloh nyní můžeme aktivity rozdělit do různých úloh.

<activity android:name=".Activity_A"
android:taskAffinity="com.affinity.of.a">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity><activity android:name=".Activity_B"
android:launchMode="singleTask"
android:taskAffinity="com.affinity.of.b"
/>

Zde mají aktivita A a aktivita B různé afinity úloh. Když je aktivita A vytvořena v úloze 1, aktivita C je spuštěna z aktivity A. Ve výchozím nastavení má každá aktivita stejnou afinitu jako její kořenová aktivita, takže jsme stále v úloze 1. Nyní je z C spuštěna aktivita B. B má jinou afinitu úlohy, takže je nyní kořenem úlohy 2, která se pak přesune do popředí. Pokud z B spustíme novou instanci aktivity C, patří C do úlohy 2, protože to je afinita úlohy kořenové aktivity (v tomto případě B). Co když se ale nyní pokusíme spustit aktivitu A z aktivity C v úloze 2? Protože A má afinitu k úloze 1, přesuneme se z úlohy 2 do úlohy 1, vyskočíme až do aktivity A a nakonec předáme záměr A.

Znalost Single Task nám pomůže lépe pochopit poslední režim spouštění; Single Instance. Stejně jako Single Task může být aktivita s Single Instance jedinou aktivitou ve všech úlohách. Rozdíl mezi nimi je v tom, že Aktivita s jednou instancí může být také jedinou aktivitou v úloze.

<activity android:name=".Activity_B"
android:launchMode="singleInstance"
android:taskAffinity="com.affinity.of.b"
/>

V tomto příkladu bude mít Aktivita B režim spuštění Jednoduchá instance. Aktivita A v úloze 1 spustí aktivitu B. Tím se aktivita B spustí v nové úloze, která se pak dostane do popředí. Aktivita B pak spustí aktivitu C. Protože Single Instance může být jedinou aktivitou v úloze, C se spustí nad aktivitou A v úloze 1 a pak se do popředí dostane úloha 1.

Příbuznost úloh také hraje roli v režimu Single Instance. Pokud aktivita B nemá afinitu k úloze, uživatel nemůže přejít zpět do úlohy 1. Pokud by aktivita B afinitu k úloze měla, uživatel bude moci přecházet mezi úlohami 1 a 2.

Znalost režimů spouštění mi pomáhá vytvářet lepší uživatelské rozhraní/UX pro mé uživatele a dokonce mi pomáhá řešit některé chyby, které mi vrtají hlavou, takže doufám, že tyto informace pomohou i vám!

Rád bych dal poděkování stránce CodeTutor na youtube od Anila Deshpandeho, která mi pomohla tento koncept lépe pochopit. Zde je první ze sedmi videí na toto téma: https://www.youtube.com/watch?v=m8sf0UkJkxo

Napsat komentář