Active: шта је то, стање Active у животном циклусу iOS

Аутор: IT Sectr Објављено: 2026-03-03 Време читања: 10 мин

Active — активно стање животног циклуса iOS апликације, у којем се она налази у првом плану, прима додирне догађаје и интерагује са корисником. Сазнајемо како функционише стање Active, које методе делегата UIApplicationDelegate су одговорне за њега и како правилно обрађивати прелазе између Active и Inactive у Swift-у.

Главно

  • Active — апликација у првом плану, UIResponder прима додирне догађаје, апликација је потпуно интерактивна
  • applicationDidBecomeActive — главна метода која сигнализира прелазак у Active на iOS-у
  • ScenePhase.active — еквивалент за SwiftUI, прати се путем Environment values
  • Повратак из Inactive — након позива, обавештења или Control Center апликација поново постаје Active
  • Ресурси — у Active стању апликација има највиши приоритет меморије и процесора

Active: какво је то стање

Active — стање животног циклуса мобилне апликације, у којем се она налази у првом плану, приказује се на екрану уређаја и активно интерагује са корисником. У овом стању апликација прима све додирне догађаје, притиске тастера, податке са акцелерометра и жироскопа, као и потпун приступ графичком процесору за рендеровање интерфејса.

На iOS-у стање Active је део петостањског модела животног циклуса: Not Running → Inactive → Active → Inactive → Background → Suspended → Not Running. На Android-у аналог је стање Activity након позива onResume, када се Activity налази на врху стека и прима кориснички унос. Active је једино стање у којем је UI потпуно интерактиван и реагује на гестове, скроловање, кликове и анимације.

Систем пружа апликацији у Active максимални приоритет процесора и RAM-а. То значи да систем неће прекинути такву апликацију при недостатку ресурса — прво ће бити истоварени позадински и суспендовани процеси. Међутим, апликација треба ефикасно да користи ресурсе како не би празнила батерију и изазивала тротлинг процесора.

За корисника Active је нормално стање рада са апликацијом. Корисник види интерфејс, може да притиска дугмад, попуњава форме, скролује фид. Сваки прекид овог стања (позив, обавештење, превлачење нагоре за Control Center) пребацује апликацију у Inactive, након чега се може вратити у Active или прећи у Background.

Како систем одређује да је апликација Active

iOS користи UIApplicationMain за управљање стањем. При преласку у Active систем позива applicationDidBecomeActive. За SwiftUI аналогни механизам је посматрање scenePhase-а путем Environment-а. Android користи onResume као индикатор активности Activity у првом плану. Оба приступа гарантују да апликација добија обавештење о промени стања и може прилагодити своје понашање.

ПлатформаМетода/догађајSwift (UIKit)SwiftUIAndroid (Kotlin)
iOSПрелазак у ActiveapplicationDidBecomeActivescenePhase == .active
iOSИзлазак из ActiveapplicationWillResignActivescenePhase == .inactive
AndroidПрелазак у ActiveonResume()
AndroidИзлазак из ActiveonPause()

Active у iOS-у: Swift, UIKit и SwiftUI

У iOS-у стање Active се обрађује путем UIApplicationDelegate. Главна метода — applicationDidBecomeActive(_:). Позива се при првом покретању апликације и при повратку из Inactive-а. Ова метода је идеално место за наставак задатака који су били суспендовани при одласку у Inactive: покретање анимација, наставак тајмера, поновно покретање сензора, провера ажурирања података на серверу.

UIKit: AppDelegate и SceneDelegate

Од iOS 13 компанија Apple је представила UISceneDelegate за подршку више прозора на iPad-у. У овом случају applicationDidBecomeActive се замењује са sceneDidBecomeActive за сваку сцену. Апликације које подржавају само један екран могу наставити да користе UIApplicationDelegate. Оба приступа се позивају у тренутку када апликација или сцена постане активна.

swift
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    // Апликација је постала активна — настављамо задатке
    func applicationDidBecomeActive(_ application: UIApplication) {
        resumeAnimations()
        restartTimers()
        refreshDataIfNeeded()
        startObservingSensors()
    }

    // Апликација губи активност — суспендујемо
    func applicationWillResignActive(_ application: UIApplication) {
        pauseAnimations()
        stopTimers()
        saveDraftData()
    }

    private func resumeAnimations() {
        UIView.animate(withDuration: 0.3) {
            // Наставак UI анимација
        }
    }

    private func refreshDataIfNeeded() {
        let lastRefresh = UserDefaults.standard.object(forKey: "lastRefresh") as? Date ?? .distantPast
        if Date().timeIntervalSince(lastRefresh) > 300 {
            fetchDataFromServer()
        }
    }
}

Код приказује правилну обраду Active у UIKit-у. applicationDidBecomeActive наставља анимације, тајмере и проверава да ли је потребно ажурирање података. applicationWillResignActive зауставља све што може трошити ресурсе и чува скице. Такав пар метода гарантује да апликација правилно реагује на промену стања.

SwiftUI: scenePhase

У SwiftUI-ју не постоји AppDelegate — управљање стањем се одвија путем Environment<ScenePhase>. Вредност .active се поставља када се сцена налази у првом плану и интерактивна је. SwiftUI аутоматски поново покреће анимације и ажурирања при повратку у Active. Програмер треба само да се претплати на onChange за извршавање споредних ефеката.

swift
import SwiftUI

@main
struct ActiveDemoApp: App {
    @Environment(\.scenePhase) private var scenePhase

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .onChange(of: scenePhase) { oldPhase, newPhase in
            switch newPhase {
            case .active:
                print("Сцена је постала активна")
                resumeWork()
            case .inactive:
                print("Сцена је постала неактивна")
                pauseWork()
            case .background:
                print("Сцена је отишла у позадину")
                saveState()
            @unknown default:
                break
            }
        }
    }

    private func resumeWork() {
        // Наставак мрежних захтева, анимација
    }

    private func pauseWork() {
        // Суспендовање временски осетљивих задатака
    }

    private func saveState() {
        // Чување стања апликације
    }
}

У SwiftUI-ју scenePhase је једини извор истине о стању апликације. onChange омогућава извршавање радњи при сваком прелазу. Важно је запамтити да је scenePhase доступан само на iOS 14+ и у SwiftUI Lifecycle-у. За UIKit апликације са SwiftUI екранима користите приступ са UIApplicationDelegate-ом.

Прелази у стање Active

Active се достиже на неколико начина. Први и очигледан — хладно покретање: корисник кликне на икону, апликација прелази из Not Running преко Inactive у Active. Други — повратак из позадине: корисник се враћа у апликацију путем App Switcher-а, апликација пролази кроз Inactive и постаје Active. Трећи — повратак из привременог прекида: корисник завршава позив, затвара Control Center или одговара на обавештење — апликација се враћа из Inactive у Active.

Ланац прелаза у Active

Not Running → Inactive → Active — хладно покретање. Background → Inactive → Active — повратак из позадине. Inactive → Active — повратак из привременог прекида. У сваком случају applicationDidBecomeActive се позива, али контекст може бити другачији. При хладном покретању пре Active-а се позива didFinishLaunchingWithOptions, при повратку из позадине — willEnterForeground. Програмер може користити ове разлике за избор стратегије обнављања стања.

СценариоПут прелазаПовратни позиви iOSПовратни позиви Android
Хладно покретањеNot Running → ActivedidFinishLaunching → didBecomeActiveonCreate → onStart → onResume
Повратак из позадинеBackground → ActivewillEnterForeground → didBecomeActiveonRestart → onStart → onResume
Повратак из SuspendedSuspended → ActivewillEnterForeground → didBecomeActiveonRestart → onStart → onResume
Након прекидаInactive → ActivedidBecomeActiveonResume

Важна напомена: при повратку из Suspended-а iOS не позива didFinishLaunchingWithOptions, јер је апликација већ учитана у меморију. То значи да се иницијализациони код постављен у овој методи не извршава поново. Програмери често заборављају на ово и премештају критичну логику у applicationWillEnterForeground или applicationDidBecomeActive за оба сценарија.

Active у Android-у: животни циклус Activity

У Android-у аналог Active-а је стање Activity након позива onResume(). Activity се сматра активним када се налази у првом плану и прима кориснички унос. Ово стање одговара врху стека Activity. Ако се друго Activity појави изнад (чак и делимично), тренутно Activity прелази у стање onPause — аналог iOS Inactive-а.

Кључна разлика Android-а — више Activity може бити активно истовремено у multi-window режиму (split screen, freeform). У овом случају Activity са којим корисник интерагује сматра се активним, а суседним — суспендованим (onPause). iOS не подржава multi-window на iPhone-у, само на iPad-у путем UIScene-а.

kotlin
class MainActivity : AppCompatActivity() {

    override fun onResume() {
        super.onResume()
        // Апликација је постала активна — настављамо задатке
        resumeCameraPreview()
        startLocationUpdates()
        activateSensors()
    }

    override fun onPause() {
        super.onPause()
        // Апликација губи активност — ослобађамо ресурсе
        releaseCamera()
        stopLocationUpdates()
        deactivateSensors()
    }

    private fun resumeCameraPreview() {
        // Покретање прегледа камере (захтева дозволе)
        cameraProvider?.unbindAll()
        cameraProvider?.bindToLifecycle(
            this,
            cameraSelector,
            preview,
            imageAnalyzer
        )
    }

    private fun startLocationUpdates() {
        val locationRequest = LocationRequest.Builder(
            Priority.PRIORITY_HIGH_ACCURACY, 5000
        ).build()
        locationClient.requestLocationUpdates(
            locationRequest,
            locationCallback,
            Looper.getMainLooper()
        )
    }
}

Код приказује обраду Active-а у Android-у путем onResume/onPause. onResume наставља рад са камером, геолокацијом и сензорима — ресурсима који треба да буду активни само када је апликација видљива кориснику. onPause ослобађа ове ресурсе како не би трошили батерију. CameraX lifecycle-aware API аутоматски зауставља преглед при onPause-у.

Најбоље праксе обраде Active

Прво правило — не извршавајте тешке операције у applicationDidBecomeActive или onResume. Учитавање података, парсирање JSON-а, рад са базом података — све то треба да буде асинхроно и да не блокира главну нит. Користите GCD (DispatchQueue) у iOS-у и Coroutines у Kotlin-у за позадинске задатке. Главна нит треба само да ажурира UI и покреће асинхроне операције.

Друго правило — синхронизујте стање при сваком повратку у Active. Корисник је могао да промени подешавања у системској апликацији, прими пусх обавештење или ажурира податке у другој апликацији. Проверавајте актуелност кеша при преласку у Active — можда су подаци застарели током одсуства корисника.

Треће правило — не ослањајте се на Active као једино стање. Апликација може прескочити Active и прећи директно из Not Running у Background (ако је покренута у позадини). На iOS-у се то дешава при покретању путем пусх обавештења са опцијом content-available. На Android-у — при покретању путем BroadcastReceiver-а. Увек проверавајте тренутно стање пре извршавања UI операција.

Четврто правило — користите Activity Result API на Android-у уместо onActivityResult. Ово омогућава обраду резултата позива камере, галерије или дозвола директно у Active стању без губитка података при поновном креирању Activity. За iOS користите async/await са UIApplication.shared.open за системске дијалоге.

swift
import UIKit

final class ActiveStateManager {
    static let shared = ActiveStateManager()
    private var isActive = false

    func setActive(_ active: Bool) {
        isActive = active
        if active {
            NotificationCenter.default.post(name: .appDidBecomeActive, object: nil)
        }
    }

    func performWhenActive(_ block: @escaping () -> Void) {
        if isActive {
            block()
        } else {
            // Одложи извршење до повратка у Active
            NotificationCenter.default.addObserver(
                forName: .appDidBecomeActive,
                object: nil,
                queue: .main
            ) { _ in
                block()
            }
        }
    }
}

extension Notification.Name {
    static let appDidBecomeActive = Notification.Name("appDidBecomeActive")
}

Код приказује менаџер стања Active који омогућава другим компонентама апликације да провере тренутно активно стање. performWhenActive или извршава блок одмах (ако је апликација активна) или одлаже извршење до повратка у Active. Ово је корисно за сервисе који морају да изврше радњу након што се корисник врати у апликацију.

Често постављана питања

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

Метода се позива сваки пут када апликација прелази у активно стање: при првом покретању, при повратку из позадине, након затварања Control Center-а или Notification Center-а, након завршетка позива. У нормалној сесији може бити позвана 5–10 пута у зависности од радњи корисника. Немојте постављати једнократну иницијализацију у ову методу.

Чиме се разликује Active од Visible на iOS-у?

Visible — неформални термин који значи да је апликација видљива на екрану, али можда не прима догађаје (на пример, делимично покривена другим прозором на iPad-у). Active — званично стање у којем је апликација и видљива и интерактивна. На iPhone-у Visible апликација је увек Active, на iPad-у је могућа ситуација Visible + Inactive.

Шта је didBecomeActive vs willEnterForeground?

willEnterForeground се позива при повратку из позадине, али апликација још увек није активна — налази се у Inactive. didBecomeActive се позива након што је апликација постала потпуно интерактивна. Ако треба извршити радњу пре него што корисник види интерфејс — користите willEnterForeground. Ако након приказивања — didBecomeActive.

Може ли апликација бити Active без видљивог UI-ја?

Не. Active подразумева да се апликација налази у првом плану и приказује на екрану. Без видљивог UI-ја апликација може бити у Background или Suspended. Изузетак — iPad multi-window, где један прозор може бити активан, а други не, али су оба видљива. VoiceOver и диктафон не мењају ово правило.

Како тестирати прелаз у Active на симулатору?

На iOS симулатору притисните Cmd+Shift+H за одлазак на почетни екран (апликација прелази у Background), затим поново кликните на икону апликације. Користите Cmd+L за закључавање екрана (willResignActive) и откључавање (didBecomeActive). За тестирање Inactive-а позовите Control Center (Cmd+Shift+; за macOS тастатуру) или Notification Center.

Резиме

  • Active — стање апликације у првом плану са потпуним приступом корисничком уносу и максималним приоритетом ресурса
  • iOS UIKit — applicationDidBecomeActive за наставак анимација, тајмера и сензора
  • SwiftUI — scenePhase .active путем Environment-а, onChange за споредне ефекте
  • Android — onResume/onPause као аналог Active/Inactive, са подршком multi-window
  • Прелази — Active се достиже из Not Running (хладно покретање), Background и Inactive
  • Ресурси — тешке операције у didBecomeActive треба да буду асинхроне, не блокирају главну нит
  • Синхронизација — провера актуелности кеша и података при сваком повратку у Active

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође