Not Running — paunang estado ng lifecycle ng isang mobile application, kung saan hindi pa ito nailunsad o natapos na ang operasyon. Alamin kung paano pinamamahalaan ng system iOS at Android ang estadong ito, anong mga kaganapan ang humahantong sa paglipat mula sa Not Running at kung paano wastong pangasiwaan ang pagsisimula at pagtatapos ng application sa Swift at Kotlin.
Mga Pangunahing Punto
Not Running — ay ang pangunahing estado ng lifecycle ng isang mobile application, kung saan hindi ito naka-load sa RAM ng device at hindi kumukonsumo ng mga system resources. Sa iOS at Android, ang estadong ito ay nangangahulugang kumpletong kawalan ng mga proseso at thread na nauugnay sa application. Nakikita ng user ang icon ng application sa desktop, ngunit ang application mismo ay hindi aktibo at wala sa listahan ng mga kamakailan.
Kapag nag-tap ang user sa icon, ang system ay gumagawa ng bagong proseso, nilo-load ang executable code sa memorya at ini-initialize ang lahat ng kinakailangang data structures. Ang prosesong ito ay tinatawag na malamig na pagsisimula (cold start) at ito ang pinaka-resource-intensive sa mga tuntunin ng oras ng pag-load.
Maaaring ilipat ng system ang application sa Not Running mula sa anumang iba pang estado. Kung ang application ay nasa background (Background) o nasuspinde (Suspended), ang operating system ay may karapatang buwagin ito kapag kulang ang RAM para sa mas prayoridad na mga gawain — halimbawa, para sa isang aktibong application sa foreground.
Dapat isaalang-alang ng developer na ang application ay maaaring tapusin ng system anumang oras kapag ito ay nasa background. Ito ay nangangahulugan na ang lahat ng hindi naka-save na data ay maaaring mawala. Samakatuwid, napakahalagang i-save ang estado sa key-value storage (UserDefaults, SharedPreferences) o sa lokal na database sa mga paglipat mula sa Active patungong Background.
Ang iOS ay gumagamit ng mga prayoridad batay sa kasalukuyang estado ng application: Ang Active ay may pinakamataas na prayoridad, pagkatapos ay Inactive, Background, Suspended at sa wakas Not Running — pinakamababang prayoridad. Ang Android ay gumagamit ng katulad na hierarchy ng proseso: ang Foreground process ay may prayoridad OOM_ADJ = 0, Visible process = 100, Service process = 200, Background process = 300, Empty process = 400. Kung mas mataas ang halaga, mas malaki ang posibilidad na ang proseso ay tatapusin kapag kulang ang memorya.
| Platform | Estado | Prayoridad ng pagbuwag | Paglalarawan |
|---|---|---|---|
| iOS | Not Running | Pinakamataas | Hindi naka-load ang application — hindi kumukonsumo ng system resource |
| iOS | Suspended | Mataas | Application sa memorya, ngunit hindi tumatakbo ang code — unang target para sa pagbuwag |
| iOS | Background | Katamtaman | Application ay gumaganap ng background task — binuwag pagkatapos ng timeout |
| iOS | Active | Mababa | Aktibong application — binuwag lamang kapag kritikal ang kakulangan ng memorya |
| Android | Empty Process | Pinakamataas | Proseso nang walang aktibong component — unang tinanggal |
| Android | Background Process | Mataas | Background na proseso nang walang nakikitang Activity |
| Android | Foreground Service | Mababa | Serbisyo na may notification — bihirang tapusin |
| Android | Foreground Process | Pinakamababa | Aktibong Activity — huling tinatapos |
Malamig na pagsisimula (cold start) ay nangyayari kapag ang application ay lumipat mula sa Not Running diretso sa Active. Ang system ay gumagawa ng bagong proseso, naglo-load ng mga klase, nag-i-initialize ng mga static field, gumagawa ng main thread at nagpapatakbo ng UI framework. Sa iOS ito ay nangangahulugang pagtawag sa application(_:didFinishLaunchingWithOptions:), sa Android — pagtawag sa Application.onCreate() at Activity.onCreate(). Ang oras ng malamig na pagsisimula ay maaaring mula 200 ms hanggang ilang segundo depende sa pagiging kumplikado ng application.
Mainit na pagsisimula (warm start o hot start) — ang application ay nasa estado ng Suspended at bumalik sa operasyon nang walang kumpletong pag-reload. Ibinabalik ng system ang huling UI stack mula sa memorya at ang user ay nagpapatuloy sa trabaho mula sa parehong lugar. Ang mainit na pagsisimula ay makabuluhang mas mabilis kaysa sa malamig na pagsisimula, dahil ang karamihan ng code ay naka-load na sa memorya. Sa iOS, ang mainit na pagsisimula ay hindi tumatawag sa application(_:didFinishLaunchingWithOptions:), applicationWillEnterForeground at applicationDidBecomeActive lamang.
Ang pagkakaiba sa pagitan ng malamig at mainit na pagsisimula ay kritikal para sa karanasan ng user. Sa malamig na pagsisimula, dapat tiyakin ng developer na ang paglunsad ay mangyari nang mabilis hangga't maaari — tamad na initialization ng modules, naantalang pag-load ng mabibigat na resources, pag-minimize ng trabaho sa main thread sa pagsisimula. Inirerekomenda ng Google ang malamig na pagsisimula na hindi hihigit sa 500 ms, Apple — hindi hihigit sa 400 ms para sa iOS.
// Pagsukat ng oras ng malamig na pagsisimula sa Android
class App : Application() {
private var startTime: Long = 0L
override fun onCreate() {
super.onCreate()
startTime = System.currentTimeMillis()
}
fun getStartupTime(): Long {
return System.currentTimeMillis() - startTime
}
}
// Pagpapatakbo ng Activity na may tamad na initialization
class MainActivity : AppCompatActivity() {
private val viewModel: MainViewModel by lazy {
ViewModelProvider(this).get(MainViewModel::class.java)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Tanging kinakailangang minimum para sa unang frame
setupNavigation()
}
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
// Mabigat na initialization pagkatapos ng rendering
initializeHeavyModules()
}
}Ipinapakita ng halimbawa ang pagsukat ng oras ng malamig na pagsisimula sa Android. Application.onCreate() ay tinatawag sa paglipat mula sa Not Running patungong Active. Ang timestamp ay naitala sa pagsisimula ng proseso. Ang Activity ay gumagamit ng tamad na initialization sa pamamagitan ng lazy-delegate upang hindi harangan ang unang frame. Ang onPostCreate ay ang pinakamainam na lugar para sa initialization ng mabibigat na modules, dahil ang UI ay na-render na.
Sa iOS, ang Not Running ay pinamamahalaan sa pamamagitan ng delegate UIApplicationDelegate. Mga pangunahing pamamaraan: ang application(_:didFinishLaunchingWithOptions:) ay tinatawag pagkatapos ng malamig na pagsisimula, ang applicationWillTerminate(_:) ay tinatawag bago ang pagtatapos ng application ng user. Maaaring tapusin ng system ang application nang hindi tinatawag ang applicationWillTerminate — halimbawa, sa emergency termination o pagbuwag ng memorya. Hindi ginagarantiya ng iOS ang pagtawag ng pamamaraang ito, kaya ang data ay dapat i-save sa applicationDidEnterBackground.
Maaaring manu-manong tapusin ng user ang application sa pamamagitan ng swipe sa App Switcher. Maaaring buwagin ng system ang application mula sa memorya sa background. Maaaring emergency na matapos (crash) ang application. Sa lahat ng kaso, lahat ng bagay na nilikha sa panahon ng paglunsad ay nawawasak. Ang estado na hindi na-save ay permanente nang mawawala. Sa iOS 13+, para sa pag-save ng estado ay inirerekomenda na gumamit ng NSUserActivity o mekanismo ng state restoration sa pamamagitan ng UIApplication.stateRestorationIdentifier.
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
// Malamig na pagsisimula: application ay lumipat mula sa Not Running
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// Initialization ng minimal na set ng serbisyo
setupAnalytics()
configureAppearance()
return true
}
// Application ay nagtatapos — tanging manu-manong pagsara
func applicationWillTerminate(
_ application: UIApplication
) {
saveCriticalData()
}
// Pag-save ng data bago pumunta sa background
func applicationDidEnterBackground(
_ application: UIApplication
) {
saveApplicationState()
}
private func saveCriticalData() {
UserDefaults.standard.synchronize()
}
private func saveApplicationState() {
let state = ["lastScreen": "main", "timestamp": Date()]
try? NSKeyedArchiver.archivedData(
withRootObject: state,
requiringSecureCoding: true
)
}
}Ipinapakita ng code ang wastong paghawak ng Not Running sa iOS. applicationWillTerminate ay tinatawag lamang sa manu-manong pagtatapos ng user. Ang pag-save ng kritikal na data ay nadoble sa applicationDidEnterBackground, dahil ang pamamaraang ito ay garantisadong tatawagin bago pumunta sa background. Ang state restoration ay nagpapahintulot na i-save ang UI stack para sa kasunod na pagbawi sa malamig na pagsisimula.
Sa Android, ang Not Running ay nangangahulugang ang proseso ng application ay hindi umiiral. Ang Linux system kung saan nakabatay ang Android ay namamahala ng mga proseso sa pamamagitan ng mekanismo ng Zygote. Sa paglunsad ng application, ang Zygote ay nag-fork ng bagong proseso, naglo-load ng Dalvik/ART at tumatawag sa Application.onCreate(). Sa Android, walang direktang analog ng applicationWillTerminate — maaaring tapusin ng system ang proseso anumang oras nang walang babala.
Kapag ang Activity ay tinawag sa unang pagkakataon, ang system ay gumagawa ng proseso, Application at Activity sa pamamagitan ng chain na onCreate → onStart → onResume. Kung ang user ay pumindot ng Back, ang Activity ay nawawasak (onDestroy) at ang proseso ay maaaring tapusin ng system. Pangunahing pagkakaiba sa iOS: sa Android, ang proseso ay maaaring magpatuloy na umiral kahit walang aktibong Activity — halimbawa, kung ang Foreground Service ay tumatakbo o may aktibong BroadcastReceiver.
// Paghawak ng Not Running sa pamamagitan ng SavedStateHandle sa ViewModel
class MainViewModel(
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
companion object {
private const val KEY_LAST_SCREEN = "last_screen"
private const val KEY_USER_DATA = "user_data"
}
fun saveCurrentState(screen: String, data: String) {
savedStateHandle[KEY_LAST_SCREEN] = screen
savedStateHandle[KEY_USER_DATA] = data
}
fun restoreState(): AppState? {
val screen = savedStateHandle.get<String>(KEY_LAST_SCREEN)
val data = savedStateHandle.get<String>(KEY_USER_DATA)
return if (screen != null && data != null) {
AppState(screen, data)
} else null
}
}
// Application — unang callback pagkatapos ng Not Running
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
initCrashReporter()
initDependencyInjection()
}
}SavedStateHandle — isang component ng Android Architecture Components na awtomatikong nagse-save ng estado sa paglipat sa Not Running at ibinabalik ito sa malamig na pagsisimula. Ang ViewModel na nilikha sa pamamagitan ng ViewModelProvider ay nakaligtas sa pag-ikot ng screen at pagkasira ng Activity. Sa pagtatapos ng proseso, ang data mula sa SavedStateHandle ay na-serialize sa Bundle at nai-save sa saved instance state.
Not Running ay nangyayari sa ilang mga dahilan. Manu-manong isinasara ng user ang application. Binubuwag ng system ang application kapag kulang ang memorya. Emergency na nagtatapos ang application na may exception. Sa Android, maaaring tapusin ng system ang proseso sa mass update ng mga application o restart ng device. Maaaring tapusin ng iOS ang application sa pag-expire ng oras ng background task (karaniwang 30 segundo).
| Dahilan | iOS | Android | Posibilidad ng pagpigil |
|---|---|---|---|
| Manu-manong pagsara ng user | Swipe sa App Switcher | Swipe mula sa Recents | Hindi — aksyon ng user |
| Kakulangan ng memorya | Pag-activate ng memory warning | onTrimMemory / LMK | Bahagya — pag-optimize ng memorya |
| Crash ng application | NSException / signal | UncaughtException / ANR | Oo — paghawak ng error at crash-reporting |
| Timeout ng background task | 30 segundo para sa Background task | 10 minuto para sa JobScheduler | Oo — tamang pagpaplano ng gawain |
| Pag-restart ng OS | Pagtawag sa applicationWillTerminate | Broadcast ACTION_SHUTDOWN | Hindi — kaganapan ng system |
| Pag-update ng application | Hindi nangyayari (iOS Sandbox) | Proseso ay natatapos sa pag-update ng APK | Hindi — pag-update ng system |
Para sa iOS, gumamit ng console logging sa applicationWillTerminate at applicationDidFinishLaunching. Magdagdag ng flag sa UserDefaults sa bawat paglunsad — kung sa susunod na pagsisimula ang flag ay wala, ang application ay natapos nang hindi tama. Sa Android gamitin ang ActivityManager.isBackgroundRestricted() upang suriin kung ang application ay maaaring magpatakbo ng mga background task. Subaybayan din ang onTrimMemory(TRIM_MEMORY_COMPLETE) — ito ay senyales na ang proseso ay tatapusin.
Unang panuntunan — huwag kailanman ipagpalagay na ang applicationWillTerminate o onDestroy ay tatawagin. I-save ang kritikal na mahalagang data sa bawat paglipat mula sa Active patungong Background. Gumamit ng key-value storage para sa mga simpleng setting at SQLite/Room para sa structured data.
Ikalawang panuntunan — sukatin ang oras ng malamig na pagsisimula at i-optimize ito. Tamad na initialization, pag-minimize ng trabaho sa main thread, pre-loading ng resources, paggamit ng SplashScreen API — lahat ng ito ay nagpapabuti sa persepsyon ng oras ng paglunsad. Inirerekomenda ng Google ang malamig na pagsisimula na mas mababa sa 200 ms para sa mahusay na UX.
Ikatlong panuntunan — ipatupad ang State Restoration. Sa iOS gamitin ang UIApplication.stateRestorationIdentifier at NSUserActivity. Sa Android gamitin ang SavedStateHandle sa ViewModel kasama ng onSaveInstanceState. Ito ay magpapahintulot sa user na magpatuloy sa trabaho mula sa parehong lugar pagkatapos ng restart ng application.
Ikaapat na panuntunan — hawakan ang launchOptions at Intent kung saan ang application ay inilunsad pagkatapos ng Not Running. Deep link, push notification, universal link — lahat ng ito ay ipinapasa sa pamamagitan ng mga parameter ng paglunsad. Dapat tama na kunin ng developer ang data na ito at idirekta ang user sa naaangkop na screen.
// Paghawak ng deep link pagkatapos ng malamig na pagsisimula
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// Pagsusuri kung dumating ang notification
if let notification = launchOptions?[.remoteNotification] as? [String: Any] {
handleNotification(notification)
}
// Pagsusuri ng deep link
if let url = launchOptions?[.url] as? URL {
handleDeepLink(url)
}
return true
}
private func handleDeepLink(_ url: URL) {
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
let screenId = components.queryItems?.first(where: { $0.name == "screen" })?.value
else { return }
openScreen(screenId)
}Ipinapakita ng code ang paghawak ng mga parameter ng paglunsad sa malamig na pagsisimula sa iOS. launchOptions ay naglalaman ng data kung saan inilunsad ng system ang application. Ang mga notification, deep link at universal link ay ipinapasa sa pamamagitan ng diksyunaryong ito. Dapat hawakan ng developer ang lahat ng posibleng senaryo ng paglunsad upang matiyak ang maayos na karanasan ng user.
Mga Madalas Itanong
Ang data na na-save sa permanenteng storage (UserDefaults, Core Data, SharedPreferences, Room) ay nananatili. Ang data sa RAM — mga variable, cache, estado ng ViewModel nang walang SavedStateHandle — ay permanente nang nawawala. Samakatuwid, napakahalagang i-save ang estado ng application sa bawat paglipat sa background.
Sa malamig na pagsisimula, tinatawag ang application(_:didFinishLaunchingWithOptions:). Sa mainit na pagsisimula (pagbabalik mula sa Suspended), ang pamamaraang ito ay hindi tinatawag — tanging ang applicationWillEnterForeground at applicationDidBecomeActive ang na-activate. Kung kailangan mong magsagawa ng aksyon lamang sa malamig na pagsisimula, mag-set ng flag sa didFinishLaunchingWithOptions.
Oo. Ang Foreground Service na may permanenteng notification ay pumipigil sa pagtatapos ng proseso ng system, kahit na ang lahat ng Activity ay nawasak. Ang Background Service (startService nang walang foreground) ay maaaring ihinto ng system anumang oras. Ang isang tumatakbong Service ay nangangahulugang ang proseso ay umiiral at ito ay hindi na Not Running.
Sa iOS simulator, tapusin ang application sa pamamagitan ng App Switcher (Cmd+Shift+H dalawang beses, swipe pataas). Sa Android emulator, gamitin ang adb shell am force-stop com.example.app o ang Stop button sa Logcat. Pagkatapos ay patakbuhin muli ang application — ito ay magiging isang malinis na malamig na pagsisimula mula sa Not Running.
Kill-switch — isang utos ng server para sa emergency na pagtatapos ng application. Ginagamit sa mga banking at corporate application para sa remote na pag-block ng access. Kung ang application ay nakatanggap ng kill command, sa susunod na malamig na pagsisimula ay i-block nito ang UI at hihilingin ang muling awtorisasyon. Sa iOS, ang kill-switch ay ipinatutupad sa pamamagitan ng remote notifications na may blocking flag.
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