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