Voor API 11 lieten we vroeger activiteiten elke nieuwe pagina op het scherm zien. Nu met Fragments en de navigatiehulpmiddelen in API 28, is het totaal mogelijk om een zeer complexe app te maken met slechts één activiteit. Activiteiten zijn echter nog steeds geweldig voor het opdelen van je app in fasen en processen. Misschien wil je alle marketing in één activiteit verdelen, en de eigenlijke app in zijn eigen activiteit hebben. Misschien wil je een sectie reserveren voor een functie, zoals een chat service. Als je weet hoe een activiteit start, kun je deze processen beter indelen op een manier die zinvol is voor je gebruikers. Zittend op het werk, kon ik nooit de lancering modi herinneren uit de top van mijn hoofd, dus ik dacht dat ik een blog over schrijven, animeren een aantal gifs om de concepten te illustreren, en dan delen met iedereen. Veel plezier!
Voordat we het over launch modes hebben, laten we eerst de rol van een taak begrijpen. Een taak bevat een verzameling van activiteiten die zijn gerangschikt in een stack genaamd de backstack. De eerste activiteit die in een taak wordt gestart is de hoofdactiviteit. Als u op de terug-knop drukt op een hoofdactiviteit, wordt niet alleen de activiteit gedood, maar ook de taak, en mogelijk de app.
Nu duiken we in enkele lanceermodi!
Stel dat je een taak hebt met een hoofdactiviteit genaamd Activiteit A, en dan een nieuwe activiteit genaamd B lanceert, B wordt naar de top van de stack geduwd. Laten we nu zeggen dat je een andere activiteit B start vanuit de B die we zojuist hebben gemaakt, je hebt nu twee instanties van activiteit B boven op elkaar gestapeld. Als een gebruiker op de terug-knop drukt, zal hij teruggaan naar een andere instantie van Activiteit B. Dit kan erg verwarrend zijn voor de gebruiker. Het stapelen en creëren van activiteiten bovenop elkaar, wat er ook gebeurt, wordt de standaard launch mode genoemd. Als er geen lanceringsmodus is gedefinieerd in de activiteit XML in het manifest, zal de activiteit de standaard lanceringsmodus gebruiken.
Nu we zien hoe de Standaardmodus verwarrend kan zijn voor de gebruiker, kunnen we nu de Single Top lanceringsmodus begrijpen. Deze startmodus voorkomt dat verschillende instanties van dezelfde activiteiten op elkaar worden gestapeld. Laten we zeggen dat Activiteit B een single top is. We kunnen de lanceringsmodi in het manifest als volgt definiëren:
///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>
Dus als je nu Activiteit B start vanuit Activiteit B, in plaats van een nieuwe instantie van B te maken en die bovenop de oude B te stapelen, wordt de intentie doorgegeven aan de huidige instantie van B. De enige manier om twee instanties van dezelfde activiteit in één taak te hebben is om een andere activiteit vanuit B te starten, en dan B te maken vanuit die activiteit. Het belangrijkste concept van de single top launch mode is dat je geen twee instanties van dezelfde activiteit bovenop elkaar kunt hebben.
Als je geen twee instanties van dezelfde single top activiteit in een taak wilt hebben terwijl je de single top launch mode gebruikt, kun je de FLAG_ACTIVITY_CLEAR_TOP constante in je intent doorgeven. Om te illustreren wat dit doet, laten we zeggen dat uw activiteitenstapel ABC is (B is nog steeds single top). Als je B start vanuit C met FLAG_ACTIVITY_CLEAR_TOP, zal je stack helemaal naar beneden springen naar B en de intent zal worden doorgegeven aan die instantie van 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);
De volgende lanceermodus heet Single Task (Enkele taak). In deze lanceringsmodus stellen we dat een activiteit slechts bij één taak kan horen in alle taken in de app. Dus vergelijkbaar met het FLAG_ACTIVITY_CLEAR_TOP gedrag, als je stack ABC is, en je lanceert B (een enkele taak) vanuit C, poppen we helemaal naar beneden naar B, en geven we de intent door aan die instantie.
<activity android:name=".Activity_B" android:launchMode="singleTask"/>
Maar wat als we willen dat B in zijn eigen taak zit? Dit is waar taakaffiniteit in het spel komt. Met taakaffiniteit kunt u bepalen tot welke taak een activiteit behoort. Standaard heeft een activiteit dezelfde taakaffiniteit als zijn hoofdactiviteit. Met taakaffiniteit kunnen we nu activiteiten scheiden in verschillende taken.
<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"
/>
Hier hebben Activiteit A en Activiteit B verschillende taakaffiniteiten. Wanneer A is gemaakt in taak 1, wordt C gestart vanuit A. Standaard heeft elke activiteit dezelfde affiniteit als zijn root, dus we zitten nog steeds in taak 1. Nu wordt B gelanceerd vanuit C. B heeft een andere affiniteit met de taak, dus is het nu de root van taak 2, die dan naar de voorgrond verschuift. Als we een nieuwe instantie van Activiteit C starten vanuit B, behoort C tot Taak 2, omdat dat de taakaffiniteit is van de hoofdactiviteit (in dit geval, B). Maar wat als we nu proberen om A te starten vanuit C in Taak 2? Aangezien de affiniteit van A taak 1 is, verschuiven we van taak 2 naar taak 1, knallen helemaal terug naar activiteit A, en geven uiteindelijk de intentie door aan A.