onStart: суть, видимость Activity на экране Android

Автор: IT Sectr Опубликовано: 2026-03-04 Время чтения: 9 мин

onStart — это метод жизненного цикла Android, который вызывается, когда Activity или Fragment становятся видимыми для пользователя. В этот момент экран появляется на дисплее устройства, но ещё не может взаимодействовать с пользователем — фокус ввода отсутствует до вызова onResume. Метод onStart идеально подходит для регистрации системных слушателей, подключения к сервисам геолокации и запуска анимаций, которые должны работать, пока компонент видим на экране. Подробнее о полном жизненном цикле Activity читайте в статье Activity Lifecycle.

Главное

  • onStart — вызывается, когда Activity или Fragment становится видимым на экране; предшествует onResume
  • Регистрация слушателей — BroadcastReceiver, LocationListener, SensorListener регистрируют в onStart и отписываются в onStop
  • Анимации — запуск анимаций, которые должны работать, пока экран видим; приостановка в onStop
  • Bound-сервисы — подключение к клиент-серверным сервисам через bindService в onStart, отключение в onStop
  • onStart vs onResume — onStart = видимость, onResume = фокус + взаимодействие; разные уровни активности экрана
  • Fragment.onStart — вызывается после Activity.onStart, когда Fragment становится видимым в контейнере
  • Пара onStart/onStop — ресурсы, подключенные в onStart, обязательно освобождают в onStop для предотвращения утечек

Суть метода onStart в Android

onStart — второй метод жизненного цикла Activity, который вызывается системой после onCreate (или после onRestart при возврате из остановленного состояния). В момент вызова onStart Activity или Fragment становятся видимыми на экране. Пользователь видит интерфейс, но экран ещё не готов к взаимодействию — фокус ввода появится только после onResume.

Метод onStart входит в «видимый срок жизни» (visible lifetime) Activity — промежуток между onStart и onStop. В течение этого периода Activity может быть частично перекрыта другими окнами (например, прозрачным Activity или диалоговым окном), но её UI остаётся видимым. Это отличает видимый срок жизни от «срока жизни на переднем плане» (onResume — onPause), когда Activity имеет полный фокус ввода.

Понимание этой трёхуровневой иерархии критически важно для правильного распределения кода. onCreate — одноразовая инициализация, onStart — подключение видимых ресурсов, onResume — монопольный доступ к эксклюзивным ресурсам. Разработчик, путающий эти уровни, рискует создать утечки памяти или некорректное поведение приложения при переключении между экранами.

onStart в Activity

В Activity метод onStart вызывается каждый раз, когда экран появляется на дисплее — как при первом запуске (после onCreate), так и при возврате из фонового режима (после onRestart). В отличие от onCreate, onStart может вызываться многократно в течение жизни экземпляра Activity, поэтому здесь размещают код, который должен выполняться каждый раз при появлении экрана.

kotlin
class DashboardActivity : AppCompatActivity() {
    private val connectivityReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            val isConnected = ... // проверка ConnectivityManager
            binding?.statusIndicator?.setColor(
                if (isConnected) Color.GREEN else Color.RED
            )
        }
    }

    override fun onStart() {
        super.onStart()
        registerReceiver(
            connectivityReceiver,
            IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
        )
        SensorManager.getInstance().registerStepCounter()
    }

    override fun onStop() {
        unregisterReceiver(connectivityReceiver)
        SensorManager.getInstance().unregisterStepCounter()
        super.onStop()
    }
}

Ключевое правило: все ресурсы, подключенные в onStart, должны быть освобождены в onStop. Это гарантирует, что когда Activity скрыта с экрана, она не потребляет батарею, не слушает системные события и не занимает память. Android Studio содержит lint-правила, предупреждающие о регистрации BroadcastReceiver без соответствующей отписки.

onStart во Fragment

onStart во Fragment тесно привязан к жизненному циклу Activity-контейнера. Fragment получает вызов onStart после того, как Activity, в котором он находится, получила onStart. Однако если Fragment добавлен в отложенном режиме (FragmentTransaction.commit() без addToBackStack), onStart может быть вызван с задержкой.

kotlin
class MapFragment : Fragment() {
    private var mapView: MapView? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        mapView = MapView(requireContext())
        return mapView!!
    }

    override fun onStart() {
        super.onStart()
        mapView?.onStart()
        LocationService.connect(requireContext())
    }

    override fun onStop() {
        mapView?.onStop()
        LocationService.disconnect()
        super.onStop()
    }
}

Специфика Fragment.onStart: если Fragment находится в ViewPager с offscreenPageLimit = 1, соседние фрагменты также получат onStart до того, как станут видимыми. Это может привести к преждевременной регистрации слушателей. Для таких случаев используют метод setUserVisibleHint() или проверку isVisible внутри onStart, чтобы регистрировать слушатели только для реально видимых фрагментов.

Разница между onStart и onResume

Главное различие между onStart и onResume — уровень активности экрана. onStart сигнализирует, что Activity видима на экране, но не обязательно находится на переднем плане. onResume сигнализирует, что Activity находится на переднем плане и имеет фокус ввода. Разница демонстрируется на примере диалогового окна: когда поверх Activity появляется Dialog, Activity теряет onResume (вызывается onPause), но остаётся видимой — onStart/onStop не вызываются.

Таблица различий наглядно показывает, в каких сценариях вызывается каждый метод:

СценарийonStartonResume
Запуск приложенияВызываетсяВызывается
Поверх Activity открыт DialogНе вызываетсяonPause (потеря фокуса)
Нажатие кнопки «Домой»onStop (скрыто)onPause → onStop
Возврат из «Недавних»onStart (видимо)onResume (фокус)
Поворот экранаonCreate → onStart→ onResume
Входящий звонокonStop (скрыто)onPause → onStop

Эта таблица помогает разработчику решить, в какой метод поместить конкретный код. Например, если приложение должно приостанавливать воспроизведение видео при любом перекрытии экрана (даже диалогом), код помещают в onPause. Если видео должно останавливаться только при полном скрытии экрана — код помещают в onStop.

Регистрация слушателей и сервисов

onStart — оптимальное место для регистрации слушателей, которые должны работать только пока Activity видима на экране. Это касается трёх основных типов системных компонентов: BroadcastReceiver для системных событий, LocationListener для геолокации и SensorListener для датчиков устройства.

BroadcastReceiver в onStart

BroadcastReceiver регистрируют динамически через Context.registerReceiver() в onStart и отписываются в onStop через unregisterReceiver(). Динамическая регистрация предпочтительнее статической (в манифесте), поскольку она ограничивает время жизни приёмника периодом видимости Activity — приложение не просыпается от системных broadcast-сообщений, когда Activity скрыта.

kotlin
private val batteryReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent) {
        val level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
        binding?.batteryText?.text = "$level%"
    }
}

override fun onStart() {
    super.onStart()
    registerReceiver(batteryReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
}

override fun onStop() {
    unregisterReceiver(batteryReceiver)
    super.onStop()
}

LocationListener и SensorListener

Геолокация и датчики — ресурсоёмкие операции. Запрос обновлений GPS в onStart и отмена в onStop гарантирует, что приложение не жжёт батарею, когда экран скрыт. Для точной настройки используют requestLocationUpdates с минимальным интервалом и дистанцией — например, 10 секунд и 10 метров, что даёт оптимальный баланс между точностью и энергопотреблением.

Анимации и onStart

Запуск анимаций в onStart, а не в onCreate, гарантирует, что анимация стартует каждый раз при появлении экрана. Если запустить анимацию в onCreate, она сработает только при первом создании Activity, но не при возврате из фонового режима. onStart вызывается каждый раз, когда Activity становится видимой, что делает его идеальным местом для запуска циклических анимаций и переходов.

kotlin
private lateinit var pulseAnimator: ValueAnimator

override fun onStart() {
    super.onStart()
    pulseAnimator.start()
    binding?.loadingIndicator?.animate()?.alpha(1f)?.start()
}

override fun onStop() {
    pulseAnimator.cancel()
    binding?.loadingIndicator?.animate()?.cancel()
    super.onStop()
}

Для анимаций, использующих ObjectAnimator или ValueAnimator, важно вызывать cancel() в onStop. Если анимация продолжает работать после скрытия Activity, она бесполезно потребляет ресурсы GPU и CPU, что снижает производительность устройства и ускоряет разряд батареи. Android Studio Profiler (графа GPU) позволяет отследить активные анимации и выявить утечки.

Правило пары onStart/onStop применимо и к работе с камерой для предпросмотра (CameraX). Открытие камеры в onStart и закрытие в onStop гарантирует, что камера не заблокирована для других приложений, когда ваше приложение не видно на экране. Нарушение этого правила — одна из частых причин негативных отзывов в Google Play.

Часто задаваемые вопросы

В чём разница между onStart и onResume для регистрации слушателей?

onStart — для слушателей, которые должны работать, пока экран видим (BroadcastReceiver, LocationListener, SensorListener). onResume — для ресурсов, требующих монопольного доступа (камера, видеозахват, распознавание речи). Слушатели системных событий не требуют монопольного доступа и могут работать при частичном перекрытии — их регистрируют в onStart. Камера должна быть активна только при полном фокусе — её открывают в onResume.

Почему onStart может не вызываться?

onStart всегда вызывается, если Activity переходит в видимое состояние. Единственный сценарий без onStart — Activity создаётся и сразу завершается (например, из-за ошибки в onCreate). В этом случае после onCreate сразу вызывается onDestroy. Но это аварийный сценарий, которого не должно быть в корректно написанном коде.

Может ли onStart быть вызван без onResume?

Да, onStart может не получить onResume, если поверх Activity сразу открывается другое Activity или прозрачное окно. Например, если после onCreate запускается экран авторизации (Activity A → Activity B), в Activity A onStart вызывается, но onResume нет — оно сразу получает onPause → onStop при перекрытии экраном B.

Сколько раз может быть вызван onStart?

onStart может вызываться многократно в течение жизни экземпляра Activity. Каждый раз, когда Activity переходит из скрытого состояния (onStop) в видимое, вызывается onStart. На практике при активном использовании приложения onStart может вызываться десятки или сотни раз за сессию.

Стоит ли загружать данные в onStart?

Загрузка данных в onStart оправдана, если данные должны обновляться каждый раз при появлении экрана. Например, лента новостей или список уведомлений. Но загрузка должна быть асинхронной — через корутины с lifecycleScope, чтобы не блокировать UI-поток. Для данных, которые не меняются между появлениями экрана, достаточно загрузить их один раз в onCreate.

Итоги

  • onStart — метод видимого срока жизни; вызывается, когда Activity или Fragment появляются на экране
  • Регистрация в onStart — BroadcastReceiver, LocationListener, SensorListener регистрируют в onStart и отписываются в onStop
  • onStart vs onResume — onStart = видимость, onResume = фокус ввода; разные уровни для разных типов ресурсов
  • Анимации — запуск циклических анимаций в onStart, остановка в onStop; предотвращает утечку ресурсов GPU
  • Fragment.onStart — привязан к Activity.onStart; в ViewPager вызывается для соседних фрагментов заранее
  • Правило пар — все ресурсы onStart должны освобождаться в onStop, иначе утечка памяти и батареи
  • Загрузка данных — в onStart загружают данные, которые должны обновляться при каждом появлении экрана

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

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

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

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