Az Android indítási mód animált puskatáblája

dec. 20, 2018 – 6 min read

Az API 11 előtt minden új oldalt a képernyőn megjelenítő tevékenységeket használtunk. Most a Fragments és az API 28 navigációs eszközeivel teljesen lehetséges, hogy nagyon összetett alkalmazást készítsünk egyetlen aktivitással. Az aktivitások azonban még mindig nagyszerűek az alkalmazás szakaszokra és folyamatokra való felosztásához. Lehet, hogy az egész marketinget egy aktivitásba akarod felosztani, a tényleges alkalmazást pedig egy saját aktivitásban szeretnéd tartani. Lehet, hogy egy szekciót egy funkciónak, például egy csevegőszolgáltatásnak szeretne fenntartani. A tevékenységindítási módok ismerete segít abban, hogy jobban feloszthassa ezeket a folyamatokat a felhasználók számára értelmes módon. A munkahelyemen ülve nem tudtam fejből megjegyezni az indítási módokat, ezért úgy gondoltam, írok erről egy blogot, animálok néhány gifet a fogalmak illusztrálására, majd megosztom mindenkivel. Jó szórakozást!

Mielőtt az indítási módokról beszélnénk, először is értsük meg a feladat szerepét. Egy feladat tevékenységek gyűjteményét tartalmazza, amelyek egy backstack nevű veremben vannak elrendezve. A feladatban elsőként indított tevékenység a gyökértevékenység. A vissza gomb megnyomása a gyökértevékenységen nem csak a tevékenységet, hanem a feladatot és esetleg az alkalmazást is megöli.

Most merüljünk el néhány indítási módban!

Tegyük fel, hogy van egy feladatunk egy A tevékenység nevű gyökértevékenységgel, majd elindítunk egy B nevű új tevékenységet, B a verem tetejére kerül. Most tegyük fel, hogy elindítunk egy másik B tevékenységet az imént létrehozott B-ből, most már két példánya lesz a B tevékenységnek egymás tetejére rakva. Ha egy felhasználó megnyomja a vissza gombot, akkor a B tevékenység egy másik példányához fog visszatérni. Ez nagyon zavaró lehet a felhasználó számára. A tevékenységek egymásra halmozását és egymáson való létrehozását, függetlenül attól, hogy mi történik, Standard indítási módnak nevezzük. Ha a manifesztben nincs a tevékenység XML-ben definiált indítási mód, akkor a tevékenység a Standard indítási módot fogja használni.

Most, hogy látjuk, hogy a Standard mód mennyire zavaró lehet a felhasználó számára, most megérthetjük a Single Top indítási módot. Ez az indítási mód megakadályozza, hogy ugyanazon tevékenységek különböző példányai egymásra halmozódjanak. Tegyük fel, hogy a B tevékenység egyetlen tetejű. Az indítási módokat a manifesztben így definiálhatjuk:

///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>

Így most, ha a B tevékenységet a B tevékenységből indítjuk, ahelyett, hogy létrehoznánk a B új példányát és a régi B tetejére halmoznánk, a szándék átkerül a B aktuális példányába. Az egyetlen módja annak, hogy egy feladatban ugyanazon tevékenység két példánya legyen, ha egy másik tevékenységet indítunk a B-ből, majd ebből a tevékenységből létrehozzuk a B-t. Az egyetlen módja annak, hogy egy feladatban ugyanannak a tevékenységnek két példánya legyen, ha egy másik tevékenységet indítunk a B-ből, majd ebből a tevékenységből létrehozzuk a B-t. A single top launch mód fő koncepciója az, hogy nem lehet ugyanannak a tevékenységnek két példánya egymásra halmozva.

Ha a single top launch mód használata során nem akarjuk, hogy ugyanannak a single top tevékenységnek 2 példánya legyen egy feladatban, akkor a szándékban átadhatjuk a FLAG_ACTIVITY_CLEAR_TOP konstanst. Annak illusztrálására, hogy ez mit tesz, tegyük fel, hogy a tevékenységi verem ABC (B még mindig single top). Ha a FLAG_ACTIVITY_CLEAR_TOP állománnyal indítod el a B-t a C-ből, akkor a verem egészen a B-ig leugrik, és a szándékot éppen a B példányának adja át.

// 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);

A következő indítási mód az úgynevezett Single Task. Ebben az indítási módban kijelentjük, hogy egy tevékenység csak egy feladathoz tartozhat az alkalmazás összes feladata során. Tehát a FLAG_ACTIVITY_CLEAR_TOP viselkedéshez hasonlóan, ha a stackünk ABC, és a C-ből elindítjuk B-t (egyetlen feladatot), akkor egészen B-ig leugrunk, és átadjuk a szándékot ennek a példánynak.

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

De mi van, ha azt szeretnénk, hogy B a saját feladatában legyen? Itt jön a képbe a feladat-affinitás. A feladat-affinitással meghatározhatjuk, hogy egy tevékenység melyik feladathoz tartozik. Alapértelmezés szerint egy tevékenységnek ugyanaz a feladat-affinitása, mint a gyökértevékenységének. A feladat-affinitással most különböző feladatokra oszthatjuk a tevékenységeket.

<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"
/>

Itt az A és a B tevékenységnek különböző feladat-affinitása van. Amikor az A-t az 1. feladatban hozzuk létre, a C-t az A-ből indítjuk el. Alapértelmezés szerint minden tevékenységnek ugyanaz az affinitása, mint a gyökerének, tehát még mindig az 1. feladatban vagyunk. Most B-t indítjuk el C-ből. B-nek más a feladat-affinitása, így most ő a Task 2 gyökere, amely így előtérbe kerül. Ha B-ből elindítjuk a C tevékenység új példányát, C a 2. feladathoz tartozik, mivel ez a gyökértevékenység (ebben az esetben B) feladataffinitása. De mi van akkor, ha most megpróbáljuk elindítani az A-t a C-ből a Task 2-ben? Mivel A affinitása az 1. feladat, a 2. feladatból az 1. feladatra váltunk, visszapattanunk egészen az A tevékenységig, és végül átadjuk a szándékot A-nak.

A Single Task ismerete segít nekünk jobban megérteni a végső indítási módot; Single Instance. Az Egyetlen feladathoz hasonlóan az Egyetlen példányt tartalmazó tevékenység is lehet az egyetlen tevékenység az összes feladatban. A különbség a kettő között az, hogy az Egyetlen példányt tartalmazó tevékenység lehet az egyetlen tevékenység egy feladatban is.

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

Ebben a példában a B tevékenység indítási módja Egyetlen példány lesz. Az 1. feladat A tevékenysége elindítja a B tevékenységet. Ezáltal a B tevékenység egy új feladatban indul el, amely így előtérbe kerül. A B tevékenység ezután elindítja a C tevékenységet. Mivel a Single Instance lehet az egyetlen tevékenység egy feladatban, a C az 1. feladatban lévő A tevékenység tetején indul el, majd az 1. feladat kerül előtérbe.

A feladat affinitása is szerepet játszik a Single Instance-ben. Ha a B tevékenységnek nincs feladat-affinitása, a felhasználó nem tud visszanavigálni az 1. feladathoz. Ha a B-nek volt feladat-affinitása, a felhasználó képes lesz oda-vissza váltani az 1. és 2. feladat között.

Az indítási módok ismerete segít nekem jobb UI/UX élményt nyújtani a felhasználóimnak, és még néhány fejfájdító hiba megoldásában is segít, remélem, ez az információ Önnek is segít!

Meg szeretném köszönni Anil Deshpande CodeTutor youtube oldalának, hogy segített jobban megérteni a koncepciót. Itt van az első a hét videó közül ebben a témában: https://www.youtube.com/watch?v=m8sf0UkJkxo

Szólj hozzá!