onResume — основи, взаимодействие с потребителя в Android

Автор: IT Sectr Публикувано: 2026-03-04 Време за четене: 10 мин

onResume — е метод от жизнения цикъл на Android, който се извиква, когато Activity или Fragment излезе на преден план и получи фокус на въвеждане. В това състояние екранът е готов за взаимодействие с потребителя: всички събития на докосване, натискания на клавиши и жестове се насочват към този компонент. onResume е работното състояние на Activity, в което приложението прекарва по-голямата част от времето си. Именно тук се отваря камерата, стартира възпроизвеждането на видео, започва разпознаването на реч и се регистрират сензорни слушатели, изискващи изключителен достъп. Прочетете повече за пълния жизнен цикъл на Activity в статията Activity Lifecycle.

Основни точки

  • onResume — Activity на преден план с фокус на въвеждане; извиква се след onStart или след връщане от диалогов прозорец
  • Изключителни ресурси — камера, микрофон, видеозаснемане се отварят в onResume и се затварят в onPause
  • Двойка onResume/onPause — ресурсите, изискващи пълен фокус, се управляват от тази двойка; регистрират се в onResume, освобождават се в onPause
  • onResume срещу onStart — onStart = видимост, onResume = взаимодействие; диалогът покрива onResume, но не и onStart
  • Времева рамка — onResume трябва да бъде бърз; дългите операции тук забавят отговора на интерфейса
  • Fragment.onResume — извиква се след Activity.onResume, когато Fragment е готов за взаимодействие
  • onResume в Jetpack — lifecycleScope и LiveData използват onResume за автоматично управление на абонаменти

Основи на метода onResume в Android

onResume — третият метод от жизнения цикъл на Activity, извикван след onStart, който сигнализира готовността на екрана за пълно взаимодействие с потребителя. В този момент Activity се намира на върха на стека от задачи (back stack), системата насочва всички входни събития към него и приложението може да започне всякакви операции, изискващи активно участие на потребителя: видеообаждания, игри, аудиозапис, рисуване върху Canvas.

onResume влиза в живота на преден план (foreground lifetime) — периода между onResume и onPause. Това е най-активният период на работа на Activity, когато приложението консумира максимални ресурси: процесора за обработка на докосвания, GPU за рендериране на анимации, камерата и микрофона за видеозаснемане. Разбирането на това ниво на жизнения цикъл е критично за оптимизиране на консумацията на енергия — ресурсите, отворени в onResume, трябва незабавно да бъдат затворени в onPause.

Според данните от Google I/O 2025, средното време, което Activity прекарва в състояние onResume по време на една сесия, е 2–5 минути за новинарски приложения и 15–30 минути за игри и месинджъри. През останалото време Activity е в състояния onPause, onStop или onDestroy. Това означава, че оптимизирането именно на onResume кода дава най-голяма печалба в производителността и живота на батерията.

onResume в Activity

В Activity методът onResume се извиква всеки път, когато екранът получи фокус на въвеждане — при първо стартиране, при връщане от друго Activity, при затваряне на диалогов прозорец, при отключване на устройството. Това е горещ метод, който може да бъде извикван много пъти по време на сесия и неговата имплементация трябва да бъде максимално лека.

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", "Неуспешно свързване на камерата", e)
            }
        }, ContextCompact.getMainExecutor(this))
    }

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

Примерът с CameraX демонстрира класическата употреба на onResume/onPause: камерата е изключителен ресурс, който може да се използва само от едно приложение в даден момент. Свързването на камерата с жизнения цикъл чрез bindToLifecycle автоматично затваря камерата в onPause, но изричното извикване на unbindAll гарантира незабавно освобождаване. Това е особено важно при превключване между Activity: камерата трябва да бъде освободена, преди друго Activity да се опита да я отвори.

onResume във Fragment

onResume във Fragment се извиква, след като съдържащото го Activity е получило onResume. Поради особеностите на FragmentManager и ViewPager обаче, моментът на извикване на onResume за Fragment може да бъде забавен спрямо Activity. Например, Fragment в ViewPager с offscreenPageLimit = 1 получава onResume едва когато стане текуща страница, а не при стартиране на 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()
    }
}

Проверката на userVisibleHint във Fragment.onResume е от значение за ViewPager: Fragment може да получи onResume, но да бъде скрит от съседна страница (например при анимиран преход). В такива случаи стартирането на видео или биометрия в onResume без проверка на видимост ще доведе до неочаквано поведение. От Fragment 1.5.0 нататък се препоръчва използването на FragmentTransaction.setMaxLifecycle() за прецизен контрол на жизнения цикъл на фрагментите в ViewPager2.

onResume срещу onStart: кога какво да използваме

Разработчиците често бъркат onStart и onResume, поставяйки код в неподходящия метод. Основно правило: onStart — за ресурси, работещи при видимост; onResume — за ресурси, изискващи фокус на въвеждане. Нека разгледаме конкретни сценарии и правилния избор на метод.

ОперацияМетодОбосновка
Абонамент за геолокацияonStart / onStopGPS може да работи при частична видимост
Отваряне на камераonResume / onPauseКамера — изключителен ресурс
BroadcastReceiveronStart / onStopСистемните събития не изискват фокус
Възпроизвеждане на видеоonResume / onPauseВидеото трябва да е видимо за потребителя
Bluetooth сканиранеonStart / onStopСканирането може да продължи на заден план
Диктофон (MediaRecorder)onResume / onPauseЗаписът изисква активен UI
Сензорни слушателиonResume / onPauseСензори за игри и жестове
Актуализиране на данниonStartПресни данни са нужни при появяване

Практическо правило: ако операцията трябва да бъде прекъсната при поява на диалогов прозорец — използвайте onResume/onPause. Ако операцията може да продължи при частично покриване на екрана — използвайте onStart/onStop. Например, видеоплейърът трябва да постави видео на пауза при отваряне на диалог (onPause), докато геолокацията може да продължи да се актуализира (остава в onStart).

Управление на изключителни ресурси

Изключителните ресурси са компоненти на устройството, които могат да се използват само от едно приложение в даден момент. Камера, микрофон, видеоизход (MediaProjection), NFC адаптер в режим на четене, USB устройства в accessory режим — всички тези ресурси трябва да се отварят в onResume и да се освобождават в onPause.

Работа с MediaRecorder

MediaRecorder се използва за запис на аудио и видео. Заявката за разрешения и подготовката на MediaRecorder се извършва в onCreate, а стартирането на запис — в onResume. Ако потребителят превключи към друго приложение, onPause спира записа, а onResume го възобновява. Това е стандартно поведение за диктофони и приложения за видеозапис.

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 и onResume

Биометричната автентикация (BiometricPrompt) трябва да се извиква само когато Activity е в onResume. Ако я извикате в onCreate или onStart, биометричният диалог може да се появи, преди Activity да завърши инициализацията, което ще доведе до неправилна обработка на резултата. Извикването в onResume гарантира, че биометричният прозорец ще бъде показан в правилния контекст.

Модели и препоръки

Нека разгледаме три проверени модела за работа с onResume, които се прилагат в комерсиални проекти: нулиране на таймера за неактивност, актуализиране на видимите данни и интеграция с Jetpack Navigation.

Нулиране на таймера за неактивност

В приложения с поверителни данни (банкиране, медицински карти) onResume се използва за нулиране на таймера за автоматично излизане. Ако потребителят активно взаимодейства с приложението, onResume се извиква при всяко преминаване между екрани и таймерът се нулира. Ако потребителят минимизира приложението, onPause спира таймера, а onResume при връщане или го нулира, или изисква повторна автентикация.

Актуализиране на данни при връщане

Списъкът, който трябва да показва актуални данни при всяко връщане на екрана, се актуализира в onResume. Например, ако потребителят е създал нов запис в друго Activity и се е върнал, onResume презарежда списъка от локалната база данни или от кеша на ViewModel. Това осигурява консистентност на данните без ръчно извикване на notifyDataSetChanged.

kotlin
override fun onResume() {
    super.onResume()
    // ActivityResultLauncher върна резултат — актуализираме списъка
    viewModel.refreshList()
    // Нулиране на таймера за неактивност
    inactivityTimer.reset()
}

Jetpack Navigation и onResume

В Jetpack Navigation onResume на фрагмента се извиква при всяко връщане към него чрез обратна навигация. Това свойство се използва за нулиране на състоянието на UI: скриване на клавиатурата, изчистване на полетата за търсене, актуализиране на заглавието на лентата с инструменти. OnBackPressedCallback в комбинация с onResume дава пълен контрол над навигацията без дублиране на код.

Често задавани въпроси

Каква е разликата между onResume и onStart с прости думи?

onStart — екранът се вижда. onResume — екранът е активен и готов за взаимодействие. Представете си: гледате телевизия (onStart), но взимате дистанционното в ръце (onResume). Телевизията винаги се вижда, но взаимодействието започва само с дистанционното. Ако някой покрие телевизора с перде — екранът престава да бъде видим (onStop). Ако ви вземат дистанционното — взаимодействието спира (onPause), но телевизорът все още се вижда.

Колко често се извиква onResume?

onResume се извиква всеки път, когато Activity получи фокус на въвеждане. Минимален брой — веднъж (при стартиране). Максималният брой зависи от сценариите на използване: превключване между екрани, отваряне на диалози, бързо заключване и отключване на устройството — всеки такъв сценарий извиква onResume при връщане на екрана.

Защо onResume е най-доброто място за отваряне на камерата?

Камерата — изключителен ресурс, достъпен само за едно приложение в даден момент. Ако отворите камерата в onCreate или onStart, тя ще остане блокирана за други приложения дори когато вашето приложение е неактивно. onResume гарантира, че камерата е отворена само когато Activity е на преден план, а onPause незабавно я затваря. Това е стандарт в Android разработката, установен в документацията на CameraX и Camera2 API.

Може ли onResume да не се извика след onStart?

Да, onResume може да не настъпи, ако Activity бъде покрито от друго Activity веднага след появяването си. Например, Activity A стартира Activity B в метода onCreate или onStart. В този случай A получава onStart → onPause → onStop, пропускайки onResume. Системата не извиква onResume, защото Activity A никога не е получило фокус на въвеждане.

Какво не трябва да се прави в onResume?

В onResume не трябва да се изпълняват дълги синхронни операции: зареждане на големи данни от мрежата, сложни SQL заявки, обработка на изображения. Методът onResume работи в UI нишката и всяко блокиране по-дълго от 100–200 ms води до забавяне на отговора на интерфейса. Всички тежки операции трябва да бъдат асинхронни — чрез корутини, RxJava или WorkManager. Също така не се препоръчва извикването на finish() в onResume без проверка — това може да доведе до безкраен цикъл на пресъздаване.

Резюме

  • onResume — състояние на преден план с фокус на въвеждане; Activity готово за взаимодействие с потребителя
  • Изключителни ресурси — камера, микрофон, видеозаснемане се отварят в onResume и се затварят в onPause
  • onResume срещу onStart — onStart за видими, onResume за активни ресурси; диалогът прекъсва onResume, но не и onStart
  • Бързодействие — onResume трябва да бъде лек; всички тежки операции асинхронни
  • Fragment.onResume — зависи от видимостта в ViewPager; проверявайте userVisibleHint или използвайте setMaxLifecycle
  • Типични задачи — нулиране на таймер, актуализиране на данни при връщане, управление на BiometricPrompt
  • Двойка onResume/onPause — ресурсите с изключителен достъп се управляват единствено от тази двойка

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също