Android Launch Mode Animated CheatSheet

Dec 20, 2018 – 6 min read

För API 11 brukade vi visa varje ny sida på skärmen. Nu med Fragments och navigeringsverktygen i API 28 är det fullt möjligt att skapa en mycket komplex app med bara en aktivitet. Aktiviteter är dock fortfarande utmärkta för att dela upp din app i steg och processer. Du kanske vill dela upp all marknadsföring i en aktivitet och ha själva appen i en egen aktivitet. Kanske vill du ha en sektion reserverad för en funktion, till exempel en chattjänst. Genom att känna till aktivitetsstartlägena kan du bättre dela upp dessa processer på ett sätt som är meningsfullt för dina användare. När jag satt på jobbet kunde jag aldrig komma ihåg startlägena utan att tänka efter, så jag tänkte att jag skulle skriva en blogg om det, animera några gifs för att illustrera begreppen och sedan dela den med alla. Njut av det!

För att prata om lanseringslägena måste vi först förstå vilken roll en uppgift spelar. En uppgift innehåller en samling aktiviteter som är ordnade i en stapel som kallas backstack. Den första aktiviteten som startas i en uppgift är rotaktiviteten. Om du trycker på bakåtknappen på en rotaktivitet dödar du inte bara aktiviteten, utan även uppgiften och eventuellt appen.

Nu ska vi dyka ner i några lanseringslägen!

Säg att du har en uppgift med en rotaktivitet som heter Aktivitet A, och sedan startar en ny aktivitet som heter B, B skjuts upp till toppen av stapeln. Låt oss nu säga att du startar en annan aktivitet B från B som vi just skapade, du kommer nu att ha två instanser av aktivitet B staplade ovanpå varandra. Om en användare trycker på bakåtknappen kommer han eller hon att gå tillbaka till en annan instans av aktivitet B. Detta kan vara mycket förvirrande för användaren. Att stapla och skapa aktiviteter ovanpå varandra, oavsett vad som händer, kallas för standardstartläge. Om det inte finns något startläge definierat i aktivitets-XML i manifestet kommer aktiviteten att använda standardstartläget.

När vi nu har sett hur standardläget kan vara förvirrande för användaren, kan vi nu förstå startläget Single Top. Det här lanseringsläget förhindrar att olika instanser av samma aktiviteter staplas ovanpå varandra. Låt oss säga att aktivitet B är en enkel topp. Vi kan definiera lanseringslägen i manifestet så här:

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

Så om du nu startar aktivitet B från aktivitet B, i stället för att skapa en ny instans av B och stapla den ovanpå den gamla B, överförs intentionen till den aktuella instansen av B. Det enda sättet att ha två instanser av samma aktivitet i en uppgift är att starta en annan aktivitet från B, och sedan skapa B från den aktiviteten. Huvudkonceptet för single top launch-läget är att du inte kan ha två instanser av samma aktivitet staplade ovanpå varandra.

Om du inte vill ha två instanser av samma single top-aktivitet i en uppgift när du använder single top launch-läget, kan du skicka konstanten FLAG_ACTIVITY_CLEAR_TOP i din avsikt. För att illustrera vad detta gör, låt oss säga att din aktivitetsstack är ABC (B är fortfarande en toppaktivitet). Om du startar B från C med FLAG_ACTIVITY_CLEAR_TOP kommer din stapel att hoppa hela vägen ner till B och intentionen kommer att skickas till just den instansen av 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);

Nästa lanseringsläge kallas Single Task (enstaka uppgift). I det här lanseringsläget anger vi att en aktivitet bara kan tillhöra en uppgift i alla uppgifter i appen. Så i likhet med beteendet FLAG_ACTIVITY_CLEAR_TOP, om din stack är ABC och du startar B (en enda aktivitet) från C, så hoppar vi hela vägen ner till B och skickar intentionen till den instansen.

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

Men hur blir det om vi vill att B ska vara i sin egen aktivitet? Det är här som uppgiftstillhörighet kommer in i bilden. Med uppgiftstillhörighet kan du definiera vilken uppgift en aktivitet tillhör. Som standard har en aktivitet samma uppgiftstillhörighet som dess rotaktivitet. Med uppgiftstillhörighet kan vi nu separera aktiviteter i olika uppgifter.

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

Här har aktivitet A och aktivitet B olika uppgiftstillhörighet. När A skapas i uppgift 1 startas C från A. Som standard har varje aktivitet samma affinitet som sin rot, så vi befinner oss fortfarande i uppgift 1. Nu startas B från C. B har en annan uppgiftstillhörighet, så den är nu roten till uppgift 2, som då flyttas till förgrunden. Om vi startar en ny instans av aktivitet C från B, hör C till uppgift 2 eftersom det är uppgiftsföreträdarskapet för rotverksamheten (i det här fallet B). Men vad händer om vi nu försöker starta A från C i uppgift 2? Eftersom A:s affinitet är uppgift 1, flyttar vi från uppgift 2 till uppgift 1, hoppar hela vägen tillbaka till aktivitet A och skickar slutligen över intentionen till A.

Med hjälp av att känna till Single Task kan vi bättre förstå det sista lanseringsläget; Single Instance. Precis som med Single Task kan en aktivitet med Single Instance vara den enda aktiviteten i alla uppgifter. Skillnaden mellan de två är att en aktivitet med Single Instance också kan vara den enda aktiviteten i en uppgift.

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

I det här exemplet kommer aktivitet B att ha ett startläge med Single Instance. Aktivitet A i uppgift 1 startar aktivitet B. Detta gör att aktivitet B startas i en ny uppgift, som sedan placeras i förgrunden. Aktivitet B startar sedan aktivitet C. Eftersom en Single Instance kan vara den enda aktiviteten i en uppgift startas C ovanpå aktivitet A i uppgift 1, och därefter hamnar uppgift 1 i förgrunden.

Task affinity spelar också en roll i Single Instance. Om aktivitet B inte har någon uppgiftstillhörighet kan en användare inte navigera tillbaka till uppgift 1. Om B har en aktivitetsförbindelse kan användaren gå fram och tillbaka mellan uppgift 1 och 2.

Vetenskap om lanseringslägen hjälper mig att skapa bättre UI/UX-upplevelser för mina användare, och hjälper mig till och med att lösa en del huvudbryggande buggar, så jag hoppas att den här informationen hjälper dig också!

Jag vill ge en eloge till Anil Deshpandes CodeTutor youtube-sida för att hjälpa mig att förstå konceptet bättre. Här är den första av sju videor om detta ämne: https://www.youtube.com/watch?v=m8sf0UkJkxo

Lämna en kommentar