Lekcja 5.3. Zatrzymywanie i ponowne uruchamianie aktywności w Androidzie

> Dodaj do ulubionych

Prawidłowe zatrzymywanie i ponowne uruchomianie aktywności to ważne procesy cyklu ich życia, dzięki którym użytkownik wie, że aplikacja funkcjonuje przez cały czas i zapisuje postęp. Oto kilka najważniejszych przypadków, w których dochodzi do wstrzymania i ponownego uruchomienia aktywności:

  • użytkownik otwiera okno Ostatnie aplikacje i przełącza się z jednej aplikacji do drugiej; aktywność w aplikacji uruchomionej obecnie na pierwszym planie zostaje zatrzymana; użytkownik powraca do aplikacji poprzez wybór ikony z ekranu głównego lub z okna Ostatnie aplikacje, a aplikacja zostaje uruchomiona ponownie;
  • użytkownik aplikacji wykonuje działanie, które uruchamia nową aktywność; po utworzeniu drugiej aktywności bieżąca aktywność zostaje zatrzymana; pierwsza aktywność zostaje ponownie uruchomiona po naciśnięciu przez użytkownika przycisku Wstecz;
  • użytkownik odbiera połączenie podczas korzystania z aplikacji na telefonie.

W klasie Activity dostępne są dwie metody cyklu życia, onStop() i onRestart(), które pozwalają precyzyjnie określić, jak aktywność ma się zachować w przypadku jej zatrzymania i ponownego uruchomienia. W przeciwieństwie do stanu wstrzymania, który powoduje częściowe przesłonienie interfejsu, w stanie zatrzymania mamy pewność, że interfejs aplikacji całkowicie zniknie z ekranu, a fokus zostanie przeniesiony na osobną aktywność (bądź na zupełnie inną aplikację).

zatrzymywanie aktywności schemat
Rysunek 1. Kiedy użytkownik opuszcza aktywność, system zatrzymuje ją poprzez wywołanie metody onStop() (1). Jeśli użytkownik wróci do aplikacji podczas zatrzymania aktywności, system wywoła metodę onRestart() (2), po której nastąpi szybkie wywołanie onStart() (3) i onResume() (4). Warto zauważyć, że niezależnie od przyczyny zatrzymania aktywności metoda onPause() jest zawsze wywoływana przed onStop()

Zatrzymywanie aktywności

Po wywołaniu metody onStop() aktywność staje się niewidoczna i powinna zwolnić prawie wszystkie zasoby, które są niepotrzebne podczas braku zainteresowania nią przez użytkownika. Jeśli system będzie musiał zwolnić pamięć, po zatrzymaniu aktywności jej egzemplarz może ulec zniszczeniu. W skrajnych przypadkach system może po prostu zakończyć proces aplikacji bez wywoływania końcowej metody zwrotnej onDestroy(). Należy zatem pamiętać o korzystaniu z metody onStop() w celu zwolnienia zasobów, które mogą spowodować potencjalny wyciek pamięci.

Choć metoda onPause() wykonywana jest wcześniej, to onStop() powinna służyć do wykonywania dużych, intensywnie obciążających procesor operacji zamykania (np. zapisu do bazy danych).

Oto przykładowa implementacja metody onStop() , za pomocą której szkic notatki zostaje zapisany w pamięci trwałej:

@Override
protected void onStop() {
    super.onStop();  // zawsze wywołuj metodę superclass jako pierwszą

    // zapisz bieżący szkic notatki, ponieważ aktywność zostaje zatrzymana
    // i chcemy mieć pewność, że postęp w pracy nad notatką nie zostanie utracony
    ContentValues values = new ContentValues();
    values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
    values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());

    getContentResolver().update(
            mUri,    // identyfikator URI notatki, która ma zostać zaktualizowana
            values,  // mapa nazw kolumn i przypisanych im nowych wartości
            null,    // nie używa polecenia SELECT
            null     // nie używa warunku WHERE
            );
}

Podczas zatrzymania aktywności jej obiekt przechowywany jest w pamięci, skąd zostanie ponownie wywołany po wznowieniu działania. Nie ma potrzeby ponownej inicjacji komponentów, które zostały utworzone podczas działania metod zwrotnych wykonywanych przed przejściem w stan wznowienia. System zachowuje również obecny stan każdego widoku w układzie, zatem jeśli użytkownik wpisze tekst w widżecie pola tekstowego, jego treść zostanie zachowana. Nie trzeba więc jej zapisywać a następnie przywracać.

Uruchamianie/ponowne uruchamianie aktywności

Kiedy aktywność wraca na pierwszy plan ze stanu zatrzymania, wywoływana jest na niej metoda onRestart(). Za każdym razem, kiedy aktywność staje się widoczna (czy to w rezultacie utworzenia czy ponownego uruchomienia) system wywołuje także metodę onStart(). Metoda onRestart() wywoływana jest jednak tylko w przypadku wznowienia aktywności ze stanu zatrzymania. Można zatem z jej pomocą odzyskać dane aplikacji — może się to okazać konieczne, jeśli aktywność była zatrzymana lecz nie została zniszczona.

Z reguły metoda onRestart() nie jest wymagana do odzyskania stanu aktywności, dlatego nie ma żadnych zaleceń odnośnie jej użycia dotyczących ogółu aplikacji. Po wznowieniu aktywności należy jednak pamiętać o ponownym zainicjowaniu zasobów, które powinny były zostać zwolnione wraz z wywołaniem metody onStop(). Trzeba je jednak także zainicjować wraz z utworzeniem aktywności po raz pierwszy (wówczas nie istnieje żaden obiekt aktywności). Z tego powodu metodę zwrotną onStart()można z reguły traktować jako odpowiednik metody onStop(), ponieważ system wywołuje onStart() zarówno podczas utworzenia jak i ponownego uruchomienia aktywności ze stanu zatrzymania.

Jeśli na przykład użytkownik zdecydował się wrócić do aplikacji po dłuższym czasie, za pomocą metody onStart() można sprawdzić aktywne funkcje systemowe:

@Override
protected void onStart() {
    super.onStart();  // zawsze wywołuj metodę nadklasy jako pierwszą
    
    // aktywność zostaje uruchomiona ponownie lub pierwszy raz
    // należy zatem upewnić się, że GPS został aktywowany
    LocationManager locationManager = 
            (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    
    if (!gpsEnabled) {
        // utwórz w tym momencie okno dialogowe z żądaniem włączenia GPS i uruchom intencję
        // z akcją android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS
        // by przenieść użytkownika do ekranu Ustawienia, gdzie po naciśnięciu „OK” będzie mógł włączyć GPS
    }
}

@Override
protected void onRestart() {
    super.onRestart();  // zawsze wywołuj metodę nadklasy jako pierwszą
    
    // aktywność zostaje ponownie uruchomiona ze stanu zatrzymania    
}

Kiedy system niszczy daną aktywność, zostaje na niej wywołana metoda onDestroy(). Ponieważ z reguły większość zasobów jest zwalniana przez metodę onStop(), w momencie wywołania metody onDestroy() większość aplikacji nie musi już niczego wykonywać. Metoda ta stanowi ostatnią szansę na zwolnienie zasobów mogących doprowadzić do wycieku pamięci — zadbaj więc o to, by zostały usunięte dodatkowe wątki, a także zatrzymaj inne długo wykonywane akcje (np. śledzenie metod).

Autor: Google

Źródło: https://developer.android.com/training/basics/activity-lifecycle/stopping.html

Tłumaczenie: Joanna Liana

Treść tej strony jest dostępna na zasadach licencji CC BY 2.5