The Android Launch Mode Animated CheatSheet

Dec 20, 2018 – 6 min read

Przed API 11, używaliśmy działań pokazujących każdą nową stronę na ekranie. Teraz, dzięki Fragmentom i narzędziom nawigacyjnym w API 28, jest całkowicie możliwe stworzenie bardzo złożonej aplikacji z tylko jedną aktywnością. Jednak działania są nadal świetne do dzielenia aplikacji na etapy i procesy. Może chcesz podzielić cały marketing na jedną aktywność, i mieć rzeczywistą aplikację w swojej własnej aktywności. Może chcesz jedną sekcję zarezerwowaną dla funkcji, takich jak usługa czatu. Znajomość trybów uruchamiania aktywności pomaga lepiej podzielić te procesy w sposób, który ma sens dla użytkowników. Siedząc w pracy, nigdy nie mogłem sobie przypomnieć trybów uruchamiania z głowy, więc pomyślałem, że napiszę o tym bloga, animuję kilka gifów, aby zilustrować koncepcje, a następnie podzielę się nim ze wszystkimi. Enjoy!

Przed rozmową o trybach uruchamiania, pozwala najpierw zrozumieć rolę zadania. Zadanie zawiera kolekcję działań, które są ułożone w stos zwany backstack. Pierwszą czynnością uruchamianą w zadaniu jest czynność główna. Naciśnięcie przycisku wstecz na aktywności root nie tylko zabija aktywność, ale zabija zadanie i ewentualnie aplikację.

Teraz zanurzmy się w niektórych trybach uruchamiania!

Powiedzmy, że masz zadanie z aktywnością root o nazwie Aktywność A, a następnie uruchomić nową aktywność o nazwie B, B zostaje przesunięty na szczyt stosu. Teraz powiedzmy, że uruchamiamy inną aktywność B z aktywności B, którą właśnie utworzyliśmy, teraz będziemy mieli dwie instancje aktywności B ułożone jedna na drugiej. Jeśli użytkownik naciśnie przycisk wstecz, wróci do innej instancji aktywności B. Może to być bardzo mylące dla użytkownika. Układanie i tworzenie aktywności jedna na drugiej, bez względu na wszystko, jest nazywane standardowym trybem uruchamiania. Jeśli nie ma zdefiniowanego trybu uruchamiania w XML aktywności w manifeście, aktywność użyje standardowego trybu uruchamiania.

Teraz, gdy widzimy, jak tryb standardowy może być denerwujący dla użytkownika, możemy teraz zrozumieć tryb uruchamiania Single Top. Ten tryb uruchamiania powstrzymuje różne instancje tych samych działań przed umieszczaniem ich jedna na drugiej. Załóżmy, że aktywność B jest pojedynczym wierzchołkiem. Możemy zdefiniować tryby uruchamiania w manifeście w następujący sposób:

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

Więc teraz, jeśli uruchomisz aktywność B z aktywności B, zamiast tworzyć nową instancję B i układać ją na wierzchu starej B, intencja jest przekazywana do bieżącej instancji B. Jedynym sposobem na posiadanie dwóch instancji tej samej aktywności w jednym zadaniu jest uruchomienie innej aktywności z B, a następnie utworzenie B z tej aktywności. Główną koncepcją trybu uruchamiania pojedynczego wierzchołka jest to, że nie można mieć dwóch instancji tej samej aktywności ułożonych jedna na drugiej.

Jeśli nie chcesz mieć 2 instancji tej samej aktywności pojedynczego wierzchołka w zadaniu podczas korzystania z trybu uruchamiania pojedynczego wierzchołka, możesz przekazać stałą FLAG_ACTIVITY_CLEAR_TOP w intencji. Aby zilustrować, co to robi, powiedzmy, że twój stos aktywności to ABC (B jest nadal pojedynczym wierzchołkiem). Jeśli uruchomisz B z C z FLAG_ACTIVITY_CLEAR_TOP, twój stos wyskoczy aż do B, a intencja zostanie przekazana do tej właśnie instancji 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);

Kolejny tryb uruchamiania nazywa się Pojedyncze zadanie. W tym trybie uruchamiania, stwierdzamy, że aktywność może należeć tylko do jednego zadania we wszystkich zadaniach w aplikacji. Więc podobnie do zachowania FLAG_ACTIVITY_CLEAR_TOP, jeśli twój stos jest ABC, a ty uruchamiasz B (pojedyncze zadanie) z C, my pop całą drogę w dół do B, i przekazać intencję do tej instancji.

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

Ale co jeśli chcemy, aby B było w swoim własnym zadaniu? Tu właśnie w grę wchodzi powinowactwo zadań. Powinowactwo zadań pozwala określić, do którego zadania należy dana czynność. Domyślnie, aktywność ma takie samo powinowactwo do zadania, jak jej główna aktywność. Dzięki temu możemy rozdzielić aktywności do różnych zadań.

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

Tutaj, aktywność A i aktywność B mają różne powinowactwa do zadań. Kiedy A jest tworzone w zadaniu 1, C jest uruchamiane z A. Domyślnie, każda aktywność ma takie samo powinowactwo jak jej root, więc nadal jesteśmy w zadaniu 1. Teraz B jest uruchamiane z C. B ma inne powinowactwo do zadania, więc jest teraz rootem zadania 2, które następnie przesuwa się na pierwszy plan. Jeśli uruchomimy nową instancję aktywności C z B, to C należy do zadania 2, ponieważ jest to powinowactwo do zadania głównego (w tym przypadku B). Ale co jeśli teraz spróbujemy uruchomić A z C w zadaniu 2? Ponieważ powinowactwo A to Zadanie 1, przechodzimy z Zadania 2 do Zadania 1, wracamy do aktywności A i ostatecznie przekazujemy intencję do A.

Znajomość trybu pojedynczego zadania pomoże nam lepiej zrozumieć ostatni tryb uruchamiania; pojedynczą instancję. Podobnie jak w przypadku trybu pojedynczego zadania, działanie z pojedynczą instancją może być jedynym działaniem we wszystkich zadaniach. Różnica między nimi polega na tym, że czynność z pojedynczą instancją może być również jedyną czynnością w zadaniu.

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

W tym przykładzie czynność B będzie miała tryb uruchamiania pojedynczej instancji. Aktywność A w zadaniu 1 uruchamia aktywność B. Dzięki temu czynność B jest uruchamiana w nowym zadaniu, które jest następnie umieszczane na pierwszym planie. Aktywność B uruchamia następnie aktywność C. Ponieważ pojedyncza instancja może być jedyną aktywnością w zadaniu, C jest uruchamiana na górze aktywności A w zadaniu 1, a następnie zadanie 1 pojawia się na pierwszym planie.

Pasowanie zadań również odgrywa rolę w trybie pojedynczej instancji. Jeśli czynność B nie ma powinowactwa z zadaniem, użytkownik nie może nawigować z powrotem do zadania 1. Jeśli B ma powinowactwo z zadaniem, użytkownik będzie mógł przechodzić tam i z powrotem pomiędzy zadaniem 1 i 2.

Wiedza o trybach uruchamiania pomaga mi tworzyć lepsze doświadczenia UI/UX dla moich użytkowników, a nawet pomaga mi rozwiązać niektóre błędy denerwujące głowę, więc mam nadzieję, że te informacje pomogą również Tobie!

Chcę dać shoutout do strony CodeTutor Anila Deshpande na youtube za pomoc w lepszym zrozumieniu tej koncepcji. Oto pierwszy z siedmiu filmów na ten temat: https://www.youtube.com/watch?v=m8sf0UkJkxo

Dodaj komentarz