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 срещу 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 или диалогов прозорец), но нейният потребителски интерфейс остава видим. Това различава видимия живот от „живота на преден план" (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 срещу onResume — onStart = видимост, onResume = фокус за въвеждане; различни нива за различни типове ресурси
  • Анимации — стартиране на циклични анимации в onStart, спиране в onStop; предотвратява изтичане на GPU ресурси
  • Fragment.onStart — обвързан с Activity.onStart; в ViewPager се извиква за съседни фрагменти предварително
  • Правило за двойки — всички onStart ресурси трябва да се освободят в onStop, иначе изтичане на памет и батерия
  • Зареждане на данни — в onStart се зареждат данни, които трябва да се актуализират при всяко появяване на екрана

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

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

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

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