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 vs 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", "Failed to bind 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 vs 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. If пользователь переключается на другое приложение, 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 мс приводит к задержке отклика интерфейса. Все тяжёлые операции должны быть асинхронными — через корутины, RxJava или WorkManager. Также не рекомендуется вызывать finish() в onResume без проверки — это может привести к бесконечному циклу пересоздания.

Итоги

  • onResume — состояние переднего плана с фокусом ввода; Activity готово к взаимодействию с пользователем
  • Эксклюзивные ресурсы — камера, микрофон, видеозахват открывают в onResume и закрывают в onPause
  • onResume vs onStart — onStart для видимых, onResume для активных ресурсов; диалог прерывает onResume, но не onStart
  • Быстродействие — onResume должен быть лёгким; все тяжёлые операции асинхронные
  • Fragment.onResume — зависит от видимости в ViewPager; проверять userVisibleHint или использовать setMaxLifecycle
  • Типичные задачи — сброс таймера, обновление данных при возврате, управление BiometricPrompt
  • Пара onResume/onPause — ресурсы с монопольным доступом управляются исключительно этой парой

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

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также