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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

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