onResume — podstawy, interakcja z użytkownikiem w Androidzie

Autor: IT Sectr Opublikowano: 2026-03-04 Czas czytania: 10 min

onResume — to metoda cyklu życia Android, która jest wywoływana, gdy Activity lub Fragment przechodzi na pierwszy plan i otrzymuje fokus wejścia. W tym stanie ekran jest gotowy do interakcji z użytkownikiem: wszystkie zdarzenia dotykowe, naciśnięcia klawiszy i gesty są kierowane do tego komponentu. onResume to roboczy stan Activity, w którym aplikacja spędza większość czasu. To tutaj otwiera się kamerę, uruchamia odtwarzanie wideo, rozpoczyna rozpoznawanie mowy i rejestruje sensoryczne listenery, wymagające wyłącznego dostępu. Więcej o pełnym cyklu życia Activity przeczytasz w artykule Activity Lifecycle.

Najważniejsze

  • onResume — Activity na pierwszym planie z fokusem wejścia; wywoływane po onStart lub po powrocie z okna dialogowego
  • Zasoby wyłączne — kamerę, mikrofon, przechwytywanie wideo otwiera się w onResume i zamyka w onPause
  • Para onResume/onPause — zasoby wymagające pełnego fokusu są zarządzane przez tę parę; rejestrowane w onResume, zwalniane w onPause
  • onResume vs onStart — onStart = widoczność, onResume = interakcja; okno dialogowe przesłania onResume, ale nie onStart
  • Czas wykonania — onResume musi być szybki; długotrwałe operacje opóźniają responsywność interfejsu
  • Fragment.onResume — wywoływane po Activity.onResume, gdy Fragment jest gotowy do interakcji
  • onResume w Jetpack — lifecycleScope i LiveData używają onResume do automatycznego zarządzania subskrypcjami

Podstawy metody onResume w Androidzie

onResume — trzecia metoda cyklu życia Activity, wywoływana po onStart, która sygnalizuje gotowość ekranu do pełnej interakcji z użytkownikiem. W tym momencie Activity znajduje się na szczycie stosu zadań (back stack), system kieruje do niego wszystkie zdarzenia wejścia, a aplikacja może rozpoczynać dowolne operacje wymagające aktywnego udziału użytkownika: połączenia wideo, gry, nagrywanie dźwięku, rysowanie na Canvas.

onResume wchodzi w skład życia na pierwszym planie (foreground lifetime) — okres między onResume a onPause. To najbardziej aktywny okres pracy Activity, gdy aplikacja zużywa maksimum zasobów: procesor do obsługi dotknięć, GPU do renderowania animacji, kamerę i mikrofon do przechwytywania wideo. Zrozumienie tego poziomu cyklu życia jest krytyczne dla optymalizacji zużycia energii — zasoby otwarte w onResume muszą być natychmiast zamknięte w onPause.

Według danych Google I/O 2025, średni czas, jaki Activity spędza w stanie onResume podczas jednej sesji, wynosi 2–5 minut dla aplikacji informacyjnych i 15–30 minut dla gier i komunikatorów. Przez resztę czasu Activity znajduje się w stanach onPause, onStop lub onDestroy. Oznacza to, że optymalizacja właśnie kodu onResume daje największe korzyści w wydajności i czasie pracy baterii.

onResume w Activity

W Activity metoda onResume jest wywoływana za każdym razem, gdy ekran otrzymuje fokus wejścia — przy pierwszym uruchomieniu, przy powrocie z innego Activity, przy zamknięciu okna dialogowego, przy odblokowaniu urządzenia. To gorąca metoda, która może być wywoływana wiele razy podczas sesji, a jej implementacja powinna być maksymalnie lekka.

kotlin
class CameraActivity : AppCompatActivity() {
    private var cameraProvider: ProcessCameraProvider? = null
    private var preview: Preview? = null

    override fun onResume() {
        super.onResume()
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        cameraProviderFuture.addListener({
            cameraProvider = cameraProviderFuture.get()
            val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
            preview = Preview.Builder().build().also {
                it.setSurfaceProvider(binding?.viewFinder?.surfaceProvider)
            }
            try {
                cameraProvider?.unbindAll()
                cameraProvider?.bindToLifecycle(
                    this, cameraSelector, preview
                )
            } catch (e: Exception) {
                Log.e("Camera", "Nie udało się powiązać kamery", e)
            }
        }, ContextCompact.getMainExecutor(this))
    }

    override fun onPause() {
        super.onPause()
        cameraProvider?.unbindAll()
        preview = null
    }
}

Przykład z CameraX demonstruje klasyczne użycie onResume/onPause: kamera to zasób wyłączny, który może być używany tylko przez jedną aplikację w danym momencie. Powiązanie kamery z cyklem życia przez bindToLifecycle automatycznie zamyka kamerę w onPause, ale jawne wywołanie unbindAll gwarantuje natychmiastowe zwolnienie. Jest to szczególnie ważne przy przełączaniu między Activity: kamera musi być zwolniona, zanim inne Activity spróbuje ją otworzyć.

onResume we Fragment

onResume we Fragment jest wywoływane po tym, jak zawierające go Activity otrzymało onResume. Jednak ze względu na specyfikę FragmentManager i ViewPager moment wywołania onResume dla Fragment może być opóźniony względem Activity. Na przykład Fragment w ViewPager z offscreenPageLimit = 1 otrzymuje onResume dopiero gdy staje się bieżącą stroną, a nie przy starcie Activity.

kotlin
class VideoPlayerFragment : Fragment() {
    private var exoPlayer: ExoPlayer? = null

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        exoPlayer = ExoPlayer.Builder(requireContext()).build()
        binding?.playerView?.player = exoPlayer
    }

    override fun onResume() {
        super.onResume()
        exoPlayer?.play()
        if (userVisibleHint) {
            startBiometricAuth()
        }
    }

    override fun onPause() {
        exoPlayer?.pause()
        stopBiometricAuth()
        super.onPause()
    }
}

Sprawdzenie userVisibleHint w Fragment.onResume jest istotne dla ViewPager: Fragment może otrzymać onResume, ale być ukryty przez sąsiednią stronę (na przykład przy animowanym przejściu). W takich przypadkach uruchomienie wideo lub biometrii w onResume bez sprawdzenia widoczności doprowadzi do nieoczekiwanego zachowania. Od Fragment 1.5.0 zaleca się używanie FragmentTransaction.setMaxLifecycle() do precyzyjnej kontroli cyklu życia fragmentów w ViewPager2.

onResume vs onStart: kiedy czego używać

Deweloperzy często mylą onStart i onResume, umieszczając kod w niewłaściwej metodzie. Główna zasada: onStart — dla zasobów działających przy widoczności; onResume — dla zasobów wymagających fokusu wejścia. Rozważmy konkretne scenariusze i prawidłowy wybór metody.

OperacjaMetodaUzasadnienie
Subskrypcja geolokalizacjionStart / onStopGPS może działać przy częściowej widoczności
Otwieranie kameryonResume / onPauseKamera — zasób wyłączny ekskluzywny
BroadcastReceiveronStart / onStopZdarzenia systemowe nie wymagają fokusu
Odtwarzanie wideoonResume / onPauseWideo musi być widoczne dla użytkownika
Skanowanie BluetoothonStart / onStopSkanowanie może działać w tle
Dyktafon (MediaRecorder)onResume / onPauseNagrywanie wymaga aktywnego UI
Listenery sensorówonResume / onPauseCzujniki do gier i gestów
Aktualizacja danychonStartŚwieże dane potrzebne przy pojawieniu się

Praktyczna zasada: jeśli operacja powinna być przerwana przy pojawieniu się okna dialogowego — używaj onResume/onPause. Jeśli operacja może być kontynuowana przy częściowym przesłonięciu ekranu — używaj onStart/onStop. Na przykład odtwarzacz wideo powinien wstrzymać wideo przy otwarciu okna dialogowego (onPause), a geolokalizacja może być aktualizowana (pozostaje w onStart).

Zarządzanie zasobami wyłącznymi

Zasoby wyłączne to komponenty urządzenia, które mogą być używane tylko przez jedną aplikację w danym momencie. Kamera, mikrofon, wyjście wideo (MediaProjection), adapter NFC w trybie odczytu, urządzenia USB w trybie accessory — wszystkie te zasoby muszą być otwierane w onResume i zwalniane w onPause.

Praca z MediaRecorder

MediaRecorder jest używany do nagrywania audio i wideo. Prośba o uprawnienia i przygotowanie MediaRecorder odbywa się w onCreate, a start nagrywania — w onResume. Jeśli użytkownik przełącza się do innej aplikacji, onPause wstrzymuje nagrywanie, a onResume je wznawia. To standardowe zachowanie dla dyktafonów i aplikacji do nagrywania wideo.

kotlin
private var mediaRecorder: MediaRecorder? = null
private var isRecording = false

override fun onResume() {
    super.onResume()
    if (isRecording) {
        mediaRecorder?.resume()
    }
}

override fun onPause() {
    if (isRecording) {
        mediaRecorder?.pause()
    }
    super.onPause()
}

BiometricPrompt i onResume

Uwierzytelnianie biometryczne (BiometricPrompt) powinno być wywoływane tylko gdy Activity znajduje się w onResume. Jeśli wywołasz je w onCreate lub onStart, okno biometrii może pojawić się zanim Activity zakończy inicjalizację, co doprowadzi do nieprawidłowego przetwarzania wyniku. Wywołanie w onResume gwarantuje, że okno biometrii zostanie pokazane w prawidłowym kontekście.

Wzorce i zalecenia

Rozważmy trzy sprawdzone wzorce pracy z onResume, które są stosowane w projektach komercyjnych: resetowanie timera nieaktywności, aktualizacja widocznych danych i integracja z Jetpack Navigation.

Resetowanie timera nieaktywności

W aplikacjach z poufnymi danymi (bankowość, karty medyczne) onResume jest używany do resetowania timera automatycznego wylogowania. Jeśli użytkownik aktywnie korzysta z aplikacji, onResume jest wywoływany przy każdym przejściu między ekranami i timer jest resetowany. Jeśli użytkownik zwinął aplikację, onPause zatrzymuje timer, a onResume przy powrocie albo go resetuje, albo żąda ponownego uwierzytelnienia.

Aktualizacja danych przy powrocie

Lista, która powinna wyświetlać aktualne dane przy każdym powrocie na ekran, jest aktualizowana w onResume. Na przykład, jeśli użytkownik utworzył nowy wpis w innym Activity i wrócił, onResume przeładowuje listę z lokalnej bazy danych lub z cache ViewModel. Zapewnia to spójność danych bez ręcznego wywoływania notifyDataSetChanged.

kotlin
override fun onResume() {
    super.onResume()
    // ActivityResultLauncher zwrócił wynik — aktualizujemy listę
    viewModel.refreshList()
    // Resetowanie timera nieaktywności
    inactivityTimer.reset()
}

Jetpack Navigation i onResume

W Jetpack Navigation onResume fragmentu jest wywoływany przy każdym powrocie do niego przez nawigację wsteczną. Ta właściwość jest używana do resetowania stanu UI: ukrycia klawiatury, wyczyszczenia pól wyszukiwania, aktualizacji nagłówka paska narzędzi. OnBackPressedCallback w połączeniu z onResume daje pełną kontrolę nad nawigacją bez duplikowania kodu.

Często zadawane pytania

Jaka jest różnica między onResume a onStart prostymi słowy?

onStart — ekran jest widoczny. onResume — ekran jest aktywny i gotowy do interakcji. Wyobraź sobie: oglądasz telewizję (onStart), ale bierzesz pilota w rękę (onResume). Telewizja jest cały czas widoczna, ale interakcja zaczyna się dopiero z pilotem. Jeśli ktoś zasłoni telewizor zasłoną — ekran przestaje być widoczny (onStop). Jeśli odbiorą ci pilota — interakcja się kończy (onPause), ale telewizor wciąż jest widoczny.

Jak często wywoływany jest onResume?

onResume jest wywoływany za każdym razem, gdy Activity otrzymuje fokus wejścia. Minimalna liczba — jeden raz (przy uruchomieniu). Maksymalna zależy od scenariuszy użycia: przełączanie między ekranami, otwieranie okien dialogowych, szybkie blokowanie i odblokowywanie urządzenia — każdy taki scenariusz wywołuje onResume przy powrocie na ekran.

Dlaczego onResume to najlepsze miejsce do otwierania kamery?

Kamera to zasób wyłączny dostępny tylko dla jednej aplikacji w danym momencie. Jeśli otworzysz kamerę w onCreate lub onStart, pozostanie ona zablokowana dla innych aplikacji nawet gdy twoja aplikacja jest nieaktywna. onResume gwarantuje, że kamera jest otwarta tylko gdy Activity znajduje się na pierwszym planie, a onPause natychmiast ją zamyka. To standard programowania Android, utrwalony w dokumentacji CameraX i Camera2 API.

Czy onResume może nie zostać wywołane po onStart?

Tak, onResume może nie nastąpić, jeśli Activity zostanie przesłonięte przez inne Activity zaraz po pojawieniu się. Na przykład Activity A uruchamia Activity B w metodzie onCreate lub onStart. W tym przypadku A otrzymuje onStart → onPause → onStop, pomijając onResume. System nie wywołuje onResume, ponieważ Activity A nigdy nie otrzymało fokusu wejścia.

Czego nie robić w onResume?

W onResume nie wolno wykonywać długich synchronizacyjnych operacji: ładowanie dużych danych z sieci, złożone zapytania SQL, przetwarzanie obrazów. Metoda onResume działa w wątku UI, a każde zablokowanie dłuższe niż 100–200 ms prowadzi do opóźnienia responsywności interfejsu. Wszystkie ciężkie operacje powinny być asynchroniczne — przez korutyny, RxJava lub WorkManager. Nie zaleca się również wywoływania finish() w onResume bez sprawdzenia — może to prowadzić do nieskończonej pętli odtwarzania.

Podsumowanie

  • onResume — stan pierwszego planu z fokusem wejścia; Activity gotowe do interakcji z użytkownikiem
  • Zasoby wyłączne — kamera, mikrofon, przechwytywanie wideo otwierane w onResume i zamykane w onPause
  • onResume vs onStart — onStart dla widocznych, onResume dla aktywnych zasobów; okno dialogowe przerywa onResume, ale nie onStart
  • Szybkość działania — onResume musi być lekki; wszystkie ciężkie operacje asynchroniczne
  • Fragment.onResume — zależy od widoczności w ViewPager; sprawdzać userVisibleHint lub używać setMaxLifecycle
  • Typowe zadania — resetowanie timera, aktualizacja danych przy powrocie, zarządzanie BiometricPrompt
  • Para onResume/onPause — zasoby z wyłącznym dostępem zarządzane wyłącznie przez tę parę

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również