Det animerede snydeblad til Android-lancering

Dec 20, 2018 – 6 min read

For API 11, brugte vi aktiviteter viser hver ny side på skærmen. Nu med Fragments og navigationsværktøjerne i API 28 er det helt muligt at lave en meget kompleks app med kun én aktivitet. Aktiviteter er dog stadig gode til at opdele din app i faser og processer. Måske ønsker du at opdele al markedsføring i én aktivitet og have selve appen i sin egen aktivitet. Måske vil du have en sektion reserveret til en funktion, f.eks. en chat-tjeneste. Når du kender aktivitetslanceringstilstandene, kan du bedre opdele disse processer på måder, der giver mening for dine brugere. Da jeg sad på arbejdet, kunne jeg aldrig huske lanceringstilstandene uden videre, så jeg tænkte, at jeg ville skrive en blog om det, animere nogle gifs for at illustrere begreberne og derefter dele den med alle. God fornøjelse!

Hvor vi taler om lanceringstilstande, skal vi først forstå, hvilken rolle en opgave spiller. En opgave indeholder en samling af aktiviteter, der er arrangeret i en stak kaldet backstack. Den første aktivitet, der lanceres i en opgave, er rodaktiviteten. Hvis du trykker på tilbage-knappen på en rodaktivitet, dræber du ikke kun aktiviteten, men også opgaven og muligvis appen.

Nu skal vi dykke ned i nogle lanceringstilstande!

Lad os sige, at du har en opgave med en rodaktivitet kaldet aktivitet A, og derefter lancerer en ny aktivitet kaldet B, B bliver skubbet til toppen af stakken. Lad os nu sige, at du starter en anden aktivitet B fra den B, vi lige har oprettet, du vil nu have to instanser af aktivitet B stablet oven på hinanden. Hvis en bruger trykker på tilbage-knappen, vil han/hun gå tilbage til en anden instans af aktivitet B. Dette kan være meget forvirrende for brugeren. Stabling og oprettelse af aktiviteter oven på hinanden, uanset hvad, kaldes standardstarttilstand. Hvis der ikke er defineret nogen lanceringstilstand i aktivitets-XML i manifestet, vil aktiviteten bruge standard-lanceringstilstand.

Nu da vi har set, hvordan Standardtilstand kan være forstyrrende for brugeren, kan vi nu forstå Single Top-lanceringstilstanden. Denne starttilstand forhindrer forskellige forekomster af de samme aktiviteter i at blive stablet oven på hinanden. Lad os sige, at aktivitet B er en enkelt top. Vi kan definere lanceringstilstande i manifestet på følgende måde:

///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å nu, hvis du starter aktivitet B fra aktivitet B, bliver hensigten i stedet for at oprette en ny instans af B og stable den oven på den gamle B overført til den aktuelle instans af B. Den eneste måde at have to instanser af den samme aktivitet i en opgave er at starte en anden aktivitet fra B og derefter oprette B fra denne aktivitet. Hovedkonceptet i single top launch-tilstand er, at du ikke kan have to instanser af den samme aktivitet stablet oven på hinanden.

Hvis du ikke ønsker 2 instanser af den samme single top-aktivitet i en opgave, mens du bruger single top launch-tilstand, kan du videregive konstanten FLAG_ACTIVITY_CLEAR_TOP i din hensigt. For at illustrere, hvad dette gør, lad os sige, at din aktivitetsstack er ABC (B er stadig single top). Hvis du starter B fra C med FLAG_ACTIVITY_CLEAR_TOP, vil din stak poppe helt ned til B, og hensigten vil blive videregivet til netop denne instans af 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);

Den næste lanceringstilstand kaldes Single Task. I denne lanceringstilstand angiver vi, at en aktivitet kun kan tilhøre én opgave i alle opgaverne i appen. Så i lighed med FLAG_ACTIVITY_CLEAR_TOP-adfærden, hvis din stak er ABC, og du starter B (en enkelt opgave) fra C, popper vi hele vejen ned til B og videregiver intentionen til denne instans.

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

Men hvad nu, hvis vi ønsker, at B skal være i sin egen opgave? Det er her, opgaveaffinitet kommer ind i billedet. Med opgaveaffinitet kan du definere, hvilken opgave en aktivitet hører til. Som standard har en aktivitet den samme opgaveaffinitet som dens rodaktivitet. Med opgaveaffinitet kan vi nu adskille aktiviteter i forskellige opgaver.

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

Her har aktivitet A og aktivitet B forskellige opgaveaffiniteter. Når A oprettes i opgave 1, startes C fra A. Som standard har hver aktivitet den samme affinitet som sin rod, så vi er stadig i opgave 1. Nu lanceres B fra C. B har en anden opgaveaffinitet, så den er nu roden til opgave 2, som derefter rykker i forgrunden. Hvis vi starter en ny instans af aktivitet C fra B, hører C til opgave 2, fordi det er den samme opgaveaffinitet som rodaktiviteten (i dette tilfælde B). Men hvad nu, hvis vi forsøger at starte A fra C i opgave 2? Da A’s affinitet er opgave 1, skifter vi fra opgave 2 til opgave 1, popper hele vejen tilbage til aktivitet A og sender til sidst hensigten videre til A.

Ved kendskab til Single Task kan vi bedre forstå den sidste lanceringstilstand; Single Instance. Ligesom Single Task kan en aktivitet med Single Instance være den eneste aktivitet på tværs af alle opgaver. Forskellen mellem de to er, at en aktivitet med Single Instance også kan være den eneste aktivitet i en opgave.

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

I dette eksempel vil aktivitet B have en lanceringstilstand på Single Instance. Aktivitet A i opgave 1 starter aktivitet B. Dette får aktivitet B til at starte i en ny opgave, som derefter sættes i forgrunden. Aktivitet B starter derefter aktivitet C. Da en Single Instance kan være den eneste aktivitet i en opgave, startes C oven på aktivitet A i opgave 1, og derefter kommer opgave 1 i forgrunden.

Task affinity spiller også en rolle i Single Instance. Hvis aktivitet B ikke har nogen opgaveaffinitet, kan en bruger ikke navigere tilbage til opgave 1. Hvis B havde aktivitetsaffinitet, vil en bruger kunne gå frem og tilbage mellem opgave 1 og 2.

Ved viden om lanceringstilstande hjælper mig med at lave bedre UI/UX-oplevelser for mine brugere og hjælper mig endda med at løse nogle hovedrystende fejl, så jeg håber, at disse oplysninger også hjælper dig!

Jeg vil gerne give et shoutout til Anil Deshpande’s CodeTutor youtube-side for at hjælpe mig med at forstå konceptet bedre. Her er den første af syv videoer om dette emne: https://www.youtube.com/watch?v=m8sf0UkJkxo

Skriv en kommentar