Mga Pangunahing Punto
App Lifecycle — isang may hangganang automaton na naglalarawan ng lahat ng posibleng estado ng isang mobile app at ang mga transition sa pagitan ng mga ito. Ang bawat estado ay tumutukoy kung ang app ay maaaring mag-execute ng code, magpakita ng UI, at kumonsumo ng mga mapagkukunan. Ang iOS at Android ay may magkatulad ngunit hindi magkaparehong modelo — ang mga pagkakaiba ay dahil sa arkitektura ng OS: ang iOS ay gumagamit ng mahigpit na kontrol sa memorya (suspended state), ang Android — flexible na pamamahala ng proseso sa pamamagitan ng onSaveInstanceState.
Sa iOS ang lifecycle ay mahigpit na nakatali sa foreground/background: ang app ay aktibo o suspendido. Sa Android ang lifecycle ay mas granular — ang Activity/Window ay dumadaan sa 6+ na estado, at ang proseso mismo ay may karagdagang lifecycle sa pamamagitan ng ProcessLifecycleOwner. Ang mga modernong app (mula 2024) ay lalong gumagamit ng mga pattern ng arkitektura na batay sa lifecycle: SwiftUI Lifecycle (iOS 16+) sa pamamagitan ng .scenePhase environment, Compose Lifecycle sa pamamagitan ng LifecycleEventObserver. Ang mga pattern na ito ay awtomatikong humahawak ng paglipat ng konteksto at pumipigil sa mga memory leak. Ayon sa Google, ang tamang pagproseso ng lifecycle sa Android ay nagbabawas ng konsumo ng memorya ng 30–40% sa panahon ng background work.
Sa iOS ang lifecycle ng app ay pinamamahalaan sa pamamagitan ng klase na UIApplicationDelegate (AppDelegate). Mga pangunahing pamamaraan: application(_:didFinishLaunchingWithOptions:) — pagsisimula sa unang paglunsad; applicationDidBecomeActive — app nakikita at handa para sa interaksyon; applicationWillResignActive — paglipat sa hindi aktibong estado (papasok na tawag, pagsasara ng kurtina); applicationDidEnterBackground — app nakatago, may ~5 segundo para mag-save ng data; applicationWillEnterForeground — pagbalik mula sa background; applicationWillTerminate — pagtatapos (tinatawag lamang para sa mga lumang app na walang suspended).
Simula sa iOS 13, ipinakilala ng Apple ang SceneDelegate (UISceneDelegate) para suportahan ang mga multi-window app sa iPad at macOS Catalyst. Pinamamahalaan ng SceneDelegate ang lifecycle ng bawat indibidwal na eksena (window): scene(_:willConnectTo:options:) — paglikha ng eksena; sceneDidBecomeActive — eksena aktibo; sceneWillResignActive — eksena nawawalan ng focus; sceneDidEnterBackground — eksena nakatago. Ang AppDelegate ay responsable para sa mga pandaigdigang kaganapan (pag-load ng data, push notification), at ang SceneDelegate — para sa UI status ng bawat window. Sa SwiftUI ang lifecycle ay pinamamahalaan sa pamamagitan ng environment value na @Environment(\.scenePhase): .active, .inactive, .background — nagbibigay ito ng pinag-isang API para sa SwiftUI at UIKit apps.
Sa Android ang lifecycle ay nagsisimula sa klase na Application — isang singleton na nilikha bago ang anumang Activity. Ang pamamaraan na Application.onCreate() — unang entry point, ginagamit para sa global initialization (Analytics, DI, Crash Reporting). Pagkatapos nito ang Activity ay ilulunsad na may pagkakasunod-sunod: onCreate() → onStart() → onResume(). Kapag na-minimize: onPause() → onStop() → onSaveInstanceState(). Kapag nawasak: onDestroy(). Kapag bumalik: onRestart() → onStart() → onResume().
ProcessLifecycleOwner (mula sa AndroidX Lifecycle 2.2+) ay sumusubaybay sa lifecycle ng buong proseso, hindi ng indibidwal na Activity. Nagbibigay ng dalawang estado: ON_RESUME (app sa foreground) at ON_STOP (app nakatago). Nalulutas ng ProcessLifecycleOwner ang problema "kailan pumunta ang app sa background" sa antas ng proseso — ito ay kritikal para sa mga SDK, library, at modular apps. Sa Jetpack Compose ang lifecycle ay pinamamahalaan sa pamamagitan ng LifecycleEventObserver at collectAsStateWithLifecycle, na awtomatikong nag-pause ng data collection sa background mode. Ang Android 14 (API 34) ay nagdagdag ng notification tungkol sa foreground service lifecycle sa pamamagitan ng Service.onTimeout — ang serbisyo ay dapat matapos sa loob ng 6 na oras, kung hindi ay pipilitin itong ihinto ng system.
| iOS | Android | Paglalarawan |
|---|---|---|
| Not Running | — | App hindi tumatakbo |
| didFinishLaunching | Application.onCreate | Unang pagsisimula sa paglunsad |
| Active | onResume | App nakikita at tumatanggap ng input |
| Inactive | onPause | Pansamantalang pagkawala ng focus (tawag, kurtina) |
| Background | onStop | App nakatago, code maaaring isagawa |
| Suspended | — | Code hindi isinasagawa, memorya nakalaan |
| Will Terminate | onDestroy | App tinatapos |
Pangunahing pagkakaiba: pinipilit ng iOS ang app sa Suspended (code hindi isinasagawa) 5-10 segundo pagkatapos pumunta sa background. Pinapayagan ng Android ang background work (serbisyo, WorkManager) para sa mas mahabang panahon, ngunit may mga limitasyon ng Doze Mode (Android 6+) at mga background restriction (Android 12+). ProcessLifecycleOwner sa Android — kahalintulad ng UIApplicationDidEnterBackgroundNotification sa iOS na may pagkakaiba na ito ay nag-trigger sa bawat transition sa background, hindi lamang pagkatapos ng pagkawala ng focus.
Pangunahing implementasyon ng AppDelegate na may paghawak ng lahat ng estado ng ikot ng buhay. Pag-save ng data sa transition sa background at pag-update ng UI sa pagbalik.
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_: UIApplication, didFinishLaunchingWithOptions lo: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { Analytics.shared.initialize(); return true }
func applicationDidBecomeActive(_: UIApplication) { NotificationCenter.default.post(name: .appDidBecomeActive, object: nil) }
func applicationWillResignActive(_: UIApplication) { NotificationCenter.default.post(name: .appWillResignActive, object: nil) }
func applicationDidEnterBackground(_: UIApplication) { CoreDataManager.shared.saveContext(); UserDefaults.standard.synchronize() }
func applicationWillEnterForeground(_: UIApplication) { NetworkManager.shared.refreshSession() }
}AppDelegate — sentral na punto ng lifecycle. applicationDidEnterBackground — kritikal na pamamaraan: ang iOS ay nagbibigay ng ~5 segundo para mag-save ng data. applicationDidBecomeActive — i-update ang UI, i-restart ang mga animation. Para sa SceneDelegate (iOS 13+) ang lifecycle logic ay ipinamamahagi sa mga eksena: sceneDidBecomeActive / sceneDidEnterBackground ay namamahala ng indibidwal na windows.
SceneDelegate para sa multi-window iPad apps. Ang bawat eksena ay may sariling lifecycle, independyente sa ibang mga window.
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_: UIScene, willConnectTo s: UISceneSession, options o: UIScene.ConnectionOptions) {
guard let ws = (_ as? UIWindowScene) else { return }
window = UIWindow(windowScene: ws)
window?.rootViewController = ViewController()
window?.makeKeyAndVisible()
}
func sceneDidBecomeActive(_: UIScene) { PlayerManager.shared.resume() }
func sceneDidEnterBackground(_: UIScene) { PlayerManager.shared.pause(); CoreDataManager.shared.saveContext() }
func sceneDidDisconnect(_: UIScene) { PlayerManager.shared.cleanup() }
}SceneDelegate namamahala ng lifecycle ng indibidwal na eksena. sceneDidBecomeActive / sceneDidEnterBackground — katumbas ng AppDelegate methods para sa isang partikular na window. sceneDidDisconnect ay tinatawag kapag isinara ang eksena (isinara ng user ang window sa iPad). Para mapanatili ang compatibility sa iOS 12 at mas luma, dapat i-duplicate ng AppDelegate ang SceneDelegate logic. Sa iOS 17+ maaari mong gamitin ang @Observable para awtomatikong mag-pause/magpatuloy ng mga gawain batay sa scenePhase.
Sinusubaybayan ng ProcessLifecycleOwner kung ang app ay nasa foreground/background sa antas ng proseso. Ito ang pinakamainam na paraan para sa pandaigdigang pamamahala ng lifecycle.
import android.app.Application
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
class MainApplication : Application() {
override fun onCreate() { super.onCreate(); ProcessLifecycleOwner.get().lifecycle.addObserver(AppLifecycleObserver()) }
}
class AppLifecycleObserver : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START) fun onEnterForeground() { Analytics.shared.onForeground(); NetworkMonitor.shared.start() }
@OnLifecycleEvent(Lifecycle.Event.ON_STOP) fun onEnterBackground() { Analytics.shared.onBackground(); NetworkMonitor.shared.stop() }
}ProcessLifecycleOwner — ang tanging tamang paraan upang subaybayan ang transition sa background sa antas ng app. Ang ON_START ay nagti-trigger kapag ang app ay naging visible (foreground), ON_STOP — kapag ganap na nakatago (background). Hindi tulad ng Activity lifecycle, ang ProcessLifecycleOwner ay hindi nakatali sa isang partikular na screen. Para sa Jetpack Compose gamitin ang LifecycleResumeEffect o collectAsStateWithLifecycle sa halip na manual na pagmamasid.
ViewModel + Lifecycle — tamang Android architecture para sa pagtatrabaho sa lifecycle. Awtomatikong nililinis ang ViewModel sa onDestroy, pumipigil sa memory leak.
import androidx.lifecycle.ViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
class TimerViewModel : ViewModel() {
private val _time = MutableLiveData<Long>()
val time: LiveData<Long> = _time
private var startTime = System.currentTimeMillis()
init { updateTime() }
private fun updateTime() { _time.value = System.currentTimeMillis() - startTime }
override fun onCleared() { super.onCleared(); Logger.d("ViewModel cleared — nagpapalaya ng mga mapagkukunan") }
}
// Sa Activity
class TimerActivity : AppCompatActivity() {
private val viewModel: TimerViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState); Logger.d("Activity created") }
override fun onResume() { super.onResume(); viewModel.time.observe(this) { Logger.d("Time: $it") } }
override fun onPause() { super.onPause(); Logger.d("Activity paused — nag-pause ng mga animation") }
override fun onDestroy() { super.onDestroy(); Logger.d("Activity destroyed — paglilinis") }
}ViewModel ay nakaligtas sa screen rotation at nawawasak lamang sa finish() Activity. onCleared() — lugar para maglabas ng mga mapagkukunan, mag-unsubscribe mula sa mga stream. Awtomatikong nag-pause ang LiveData ng pagmamasid sa onPause at nagpapatuloy sa onResume — nagbibigay ng proteksyon laban sa mga leak at crash sa panahon ng background work. Sa Compose gamitin ang collectAsStateWithLifecycle() para sa parehong layunin.
Mga Madalas Itanong
Kapag nagmi-minimize, ang app ay lumipat mula active patungong inactive (sandali), pagkatapos ay sa background. Pagkatapos ng ilang segundo ang system ay maaaring ilipat ito sa suspended — code hindi isinasagawa, memorya nakalaan. Kapag kulang ang memorya, ang suspended app ay terminate (hindi tinatawag ang willTerminate). I-save ang data sa applicationDidEnterBackground — ito ang huling garantisadong punto para sa pag-save.
Pinakamababang kinakailangan: applicationDidEnterBackground — i-save ang data ng user; applicationWillEnterForeground — i-update ang UI; sa Android onPause — i-pause ang mga animation/sensor. Pinapasimple ng ProcessLifecycleOwner ang paghawak: onResume — onPause para sa foreground, onStart — onStop para sa visibility. Ang iba pang mga estado ay hawakan kung kinakailangan — hindi lahat ng estado ay kritikal para sa bawat app.
AppDelegate — pandaigdigang delegado ng buong app (paglunsad, transition sa background). Ang SceneDelegate (iOS 13+) ay namamahala ng lifecycle ng indibidwal na window (eksena) — sa multi-window iPad apps bawat eksena ay may sariling lifecycle. Para sa iOS 12 at mas luma, ang buong lifecycle ay hinahawakan sa pamamagitan ng AppDelegate. Mula iPadOS 16+ ang SceneDelegate ay mandatory para sa Stage Manager.
ProcessLifecycleOwner — component mula sa AndroidX Lifecycle na sumusubaybay sa lifecycle ng buong app (proseso), hindi ng indibidwal na Activity. Nagbibigay ng dalawang pangunahing kaganapan: ON_RESUME (app sa foreground) at ON_STOP (app sa background). Ginagamit para sa initialization/paglilinis ng mga SDK, analytics, network monitors — lahat ng dapat tumugon sa transition ng app sa background, anuman ang kasalukuyang screen.
Sa Jetpack Compose gamitin ang LifecycleEventObserver sa pamamagitan ng LocalLifecycleOwner.current.lifecycle o ang function na collectAsStateWithLifecycle(). Para sa Compose screens ilapat ang LifecycleResumeEffect — kahalintulad ng DisposableEffect na tumatakbo sa onResume at nagli-linis sa onPause. lifecycleScope.launchWhenResumed — coroutine na awtomatikong nag-pause sa background.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din