Not Running — मोबाइल ऐप्लिकेशन के जीवनचक्र की प्रारंभिक अवस्था जिसमें यह अभी तक लॉन्च नहीं हुआ है या पहले ही काम समाप्त कर चुका है। जानें कि iOS और Android इस अवस्था को कैसे प्रबंधित करते हैं, कौन सी घटनाएँ Not Running से संक्रमण की ओर ले जाती हैं और Swift और Kotlin में ऐप्लिकेशन लॉन्च और समाप्ति को सही तरीके से कैसे संभालें।
मुख्य बातें
Not Running मोबाइल ऐप्लिकेशन के जीवनचक्र की मूल अवस्था है जिसमें यह डिवाइस की RAM में लोड नहीं है और सिस्टम संसाधनों का उपभोग नहीं करता। iOS और Android में, इस अवस्था का अर्थ है ऐप्लिकेशन से जुड़ी प्रक्रियाओं और थ्रेड्स की पूर्ण अनुपस्थिति। उपयोगकर्ता होम स्क्रीन पर ऐप आइकन देखता है, लेकिन ऐप्लिकेशन स्वयं सक्रिय नहीं है और हाल के ऐप्स की सूची में नहीं है।
जब उपयोगकर्ता ऐप आइकन पर टैप करता है, तो सिस्टम एक नई प्रक्रिया बनाता है, निष्पादन योग्य कोड को मेमोरी में लोड करता है और सभी आवश्यक डेटा संरचनाओं को आरंभ करता है। इस प्रक्रिया को कोल्ड स्टार्ट कहा जाता है और लोड समय के मामले में यह सबसे अधिक संसाधन-गहन है।
सिस्टम ऐप्लिकेशन को किसी भी अन्य अवस्था से Not Running में ले जा सकता है। यदि ऐप्लिकेशन बैकग्राउंड या Suspended में है, तो ऑपरेटिंग सिस्टम को उच्च प्राथमिकता वाले कार्यों के लिए पर्याप्त RAM न होने पर इसे अनलोड करने का अधिकार है — उदाहरण के लिए, सक्रिय अग्रभूमि ऐप्लिकेशन के लिए।
डेवलपर को ध्यान रखना चाहिए कि सिस्टम किसी भी क्षण ऐप्लिकेशन को समाप्त कर सकता है जब वह बैकग्राउंड में हो। इसका मतलब है कि सभी असहेज किया गया डेटा खो सकता है। इसलिए, Active से Background में संक्रमण के दौरान की-वैल्यू स्टोर (UserDefaults, SharedPreferences) या स्थानीय डेटाबेस में अवस्था सहेजना अत्यंत महत्वपूर्ण है।
iOS ऐप्लिकेशन की वर्तमान अवस्था के आधार पर प्राथमिकताओं का उपयोग करता है: Active की सर्वोच्च प्राथमिकता है, उसके बाद Inactive, Background, Suspended, और अंत में Not Running — न्यूनतम प्राथमिकता। Android समान प्रक्रिया पदानुक्रम का उपयोग करता है: Foreground प्रक्रिया की प्राथमिकता OOM_ADJ = 0 है, Visible प्रक्रिया = 100, Service प्रक्रिया = 200, Background प्रक्रिया = 300, Empty प्रक्रिया = 400। मान जितना अधिक होगा, मेमोरी कम होने पर प्रक्रिया के समाप्त होने की संभावना उतनी ही अधिक होगी।
| प्लेटफ़ॉर्म | अवस्था | अनलोड प्राथमिकता | विवरण |
|---|---|---|---|
| iOS | Not Running | सर्वोच्च | ऐप्लिकेशन लोड नहीं — कोई सिस्टम संसाधन उपभोग नहीं |
| iOS | Suspended | उच्च | ऐप्लिकेशन मेमोरी में लेकिन कोड निष्पादित नहीं — अनलोड करने का पहला लक्ष्य |
| iOS | Background | मध्यम | ऐप्लिकेशन बैकग्राउंड कार्य निष्पादित कर रहा — टाइमआउट के बाद अनलोड |
| iOS | Active | निम्न | सक्रिय ऐप्लिकेशन — केवल गंभीर मेमोरी दबाव पर अनलोड |
| Android | Empty Process | सर्वोच्च | बिना सक्रिय घटकों वाली प्रक्रिया — पहले हटाई जाती है |
| Android | Background Process | उच्च | बिना दृश्य Activity वाली बैकग्राउंड प्रक्रिया |
| Android | Foreground Service | निम्न | नोटिफिकेशन वाली सेवा — शायद ही कभी समाप्त होती है |
| Android | Foreground Process | न्यूनतम | सक्रिय Activity — सबसे अंत में समाप्त होती है |
कोल्ड स्टार्ट तब होता है जब ऐप्लिकेशन Not Running से सीधे Active में संक्रमण करता है। सिस्टम एक नई प्रक्रिया बनाता है, क्लासेस लोड करता है, स्टैटिक फ़ील्ड आरंभ करता है, मुख्य थ्रेड बनाता है और UI फ्रेमवर्क शुरू करता है। iOS पर, इसका अर्थ है application(_:didFinishLaunchingWithOptions:) को कॉल करना, Android पर — Application.onCreate() और Activity.onCreate() को कॉल करना। कोल्ड स्टार्ट का समय ऐप्लिकेशन की जटिलता के आधार पर 200 ms से लेकर कई सेकंड तक हो सकता है।
वॉर्म स्टार्ट (या हॉट स्टार्ट) — ऐप्लिकेशन Suspended अवस्था में था और बिना पूर्ण पुनःलोड के काम फिर से शुरू करता है। सिस्टम मेमोरी से अंतिम UI स्टैक को पुनर्स्थापित करता है, और उपयोगकर्ता उसी स्थान से काम जारी रखता है। वॉर्म स्टार्ट कोल्ड स्टार्ट से काफी तेज़ होता है क्योंकि अधिकांश कोड पहले से ही मेमोरी में लोड है। iOS पर, वॉर्म स्टार्ट application(_:didFinishLaunchingWithOptions:) को कॉल नहीं करता, केवल applicationWillEnterForeground और applicationDidBecomeActive को कॉल करता है।
कोल्ड और वॉर्म स्टार्ट के बीच का अंतर उपयोगकर्ता अनुभव के लिए महत्वपूर्ण है। कोल्ड स्टार्ट के दौरान, डेवलपर को यह सुनिश्चित करना चाहिए कि लॉन्च यथासंभव तेज़ी से हो — मॉड्यूल की आलसी आरंभीकरण, भारी संसाधनों का विलंबित लोडिंग, स्टार्टअप पर मुख्य थ्रेड में काम को कम करना। Google अनुशंसा करता है कोल्ड स्टार्ट 500 ms से अधिक न हो, Apple — iOS के लिए 400 ms से अधिक न हो।
// Android में कोल्ड स्टार्ट समय मापन
class App : Application() {
private var startTime: Long = 0L
override fun onCreate() {
super.onCreate()
startTime = System.currentTimeMillis()
}
fun getStartupTime(): Long {
return System.currentTimeMillis() - startTime
}
}
// आलसी आरंभीकरण के साथ Activity प्रारंभ
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)
// पहले फ्रेम के लिए केवल आवश्यक न्यूनतम
setupNavigation()
}
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
// रेंडरिंग के बाद भारी आरंभीकरण
initializeHeavyModules()
}
}उदाहरण Android में कोल्ड स्टार्ट समय मापन दिखाता है। Application.onCreate() Not Running से Active में संक्रमण पर कॉल किया जाता है। टाइमस्टैम्प प्रक्रिया प्रारंभ होने पर रिकॉर्ड किया जाता है। Activity पहले फ्रेम को ब्लॉक करने से बचने के लिए lazy डेलिगेट के माध्यम से आलसी आरंभीकरण का उपयोग करता है। onPostCreate भारी मॉड्यूल को आरंभ करने के लिए सर्वोत्तम स्थान है क्योंकि UI पहले ही रेंडर हो चुका है।
iOS में, Not Running को UIApplicationDelegate प्रोटोकॉल के माध्यम से प्रबंधित किया जाता है। मुख्य विधियाँ: application(_:didFinishLaunchingWithOptions:) कोल्ड स्टार्ट के बाद कॉल किया जाता है, applicationWillTerminate(_:) उपयोगकर्ता द्वारा ऐप्लिकेशन समाप्त करने से पहले कॉल किया जाता है। हालाँकि, सिस्टम applicationWillTerminate को कॉल किए बिना ऐप्लिकेशन समाप्त कर सकता है — उदाहरण के लिए, आपातकालीन समाप्ति या मेमोरी दबाव पर। iOS इस विधि के कॉल होने की गारंटी नहीं देता, इसलिए डेटा applicationDidEnterBackground में सहेजा जाना चाहिए।
उपयोगकर्ता App Switcher में स्वाइप करके मैन्युअल रूप से ऐप्लिकेशन समाप्त कर सकता है। सिस्टम बैकग्राउंड में रहते हुए ऐप्लिकेशन को मेमोरी से अनलोड कर सकता है। ऐप्लिकेशन क्रैश हो सकता है। सभी मामलों में, लॉन्च के दौरान बनाई गई सभी ऑब्जेक्ट नष्ट हो जाती हैं। जो अवस्था सहेजी नहीं गई, वह हमेशा के लिए खो जाती है। iOS 13+ में, अवस्था को संरक्षित करने के लिए NSUserActivity या UIApplication.stateRestorationIdentifier के माध्यम से अवस्था पुनर्स्थापना तंत्र का उपयोग करने की अनुशंसा की जाती है।
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
// कोल्ड स्टार्ट: ऐप्लिकेशन Not Running से संक्रमित हुआ
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// न्यूनतम सेवाओं का सेट आरंभ करना
setupAnalytics()
configureAppearance()
return true
}
// ऐप्लिकेशन काम समाप्त करता है — केवल मैन्युअल बंद
func applicationWillTerminate(
_ application: UIApplication
) {
saveCriticalData()
}
// बैकग्राउंड में जाने से पहले डेटा सहेजना
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
)
}
}कोड iOS पर सही Not Running हैंडलिंग दिखाता है। applicationWillTerminate केवल तब कॉल किया जाता है जब उपयोगकर्ता मैन्युअल रूप से ऐप समाप्त करता है। महत्वपूर्ण डेटा की सहेजना applicationDidEnterBackground में दोहराई जाती है क्योंकि यह विधि बैकग्राउंड में जाने से पहले कॉल होने की गारंटी है। अवस्था पुनर्स्थापना कोल्ड स्टार्ट के दौरान बाद में पुनर्प्राप्ति के लिए UI स्टैक को सहेजने की अनुमति देती है।
Android में, Not Running का अर्थ है कि ऐप्लिकेशन प्रक्रिया मौजूद नहीं है। Android के अंतर्निहित Linux सिस्टम Zygote तंत्र के माध्यम से प्रक्रियाओं का प्रबंधन करता है। जब कोई ऐप्लिकेशन लॉन्च होता है, Zygote एक नई प्रक्रिया फोर्क करता है, Dalvik/ART लोड करता है और Application.onCreate() कॉल करता है। Android में applicationWillTerminate का कोई सीधा समकक्ष नहीं है — सिस्टम बिना चेतावनी के किसी भी समय प्रक्रिया समाप्त कर सकता है।
जब पहली बार Activity कॉल किया जाता है, सिस्टम श्रृंखला onCreate → onStart → onResume के माध्यम से प्रक्रिया, Application और Activity बनाता है। यदि उपयोगकर्ता Back दबाता है, तो Activity नष्ट हो जाती है (onDestroy), और प्रक्रिया सिस्टम द्वारा समाप्त की जा सकती है। iOS से एक मुख्य अंतर: Android में, प्रक्रिया सक्रिय Activities के बिना भी मौजूद रह सकती है — उदाहरण के लिए, यदि Foreground Service चल रही है या सक्रिय BroadcastReceiver है।
// ViewModel में SavedStateHandle के माध्यम से Not Running संभालना
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 — Not Running के बाद पहला कॉलबैक
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
initCrashReporter()
initDependencyInjection()
}
}SavedStateHandle Android Architecture Components का एक घटक है जो Not Running में संक्रमण के दौरान स्वचालित रूप से अवस्था सहेजता है और कोल्ड स्टार्ट पर इसे पुनर्स्थापित करता है। ViewModelProvider के माध्यम से बनाया गया ViewModel स्क्रीन रोटेशन और Activity विनाश से बच जाता है। जब प्रक्रिया समाप्त होती है, SavedStateHandle से डेटा Bundle में क्रमबद्ध होता है और सहेजी गई इंस्टेंस अवस्था में संग्रहीत होता है।
Not Running कई कारणों से होता है। उपयोगकर्ता मैन्युअल रूप से ऐप्लिकेशन बंद करता है। सिस्टम मेमोरी की कमी पर ऐप्लिकेशन अनलोड करता है। ऐप्लिकेशन एक अपवाद के साथ क्रैश होता है। Android पर, सिस्टम सामूहिक ऐप अपडेट या डिवाइस रिबूट के दौरान प्रक्रिया समाप्त कर सकता है। iOS बैकग्राउंड कार्य टाइमआउट (आमतौर पर 30 सेकंड) पर ऐप्लिकेशन समाप्त कर सकता है।
| कारण | iOS | Android | रोका जा सकता है |
|---|---|---|---|
| उपयोगकर्ता द्वारा मैन्युअल बंद | App Switcher में स्वाइप | Recents से स्वाइप | नहीं — उपयोगकर्ता क्रिया |
| मेमोरी की कमी | मेमोरी चेतावनी सक्रिय | onTrimMemory / LMK | आंशिक रूप से — मेमोरी अनुकूलन |
| ऐप्लिकेशन क्रैश | NSException / सिग्नल | UncaughtException / ANR | हाँ — त्रुटि प्रबंधन और क्रैश रिपोर्टिंग |
| बैकग्राउंड कार्य टाइमआउट | बैकग्राउंड कार्य के लिए 30 सेकंड | JobScheduler के लिए 10 मिनट | हाँ — सही कार्य शेड्यूलिंग |
| OS रिबूट | applicationWillTerminate कॉल | Broadcast ACTION_SHUTDOWN | नहीं — सिस्टम घटना |
| ऐप अपडेट | नहीं होता (iOS सैंडबॉक्स) | APK अपडेट पर प्रक्रिया समाप्त | नहीं — सिस्टम अपडेट |
iOS के लिए, applicationWillTerminate और applicationDidFinishLaunching में कंसोल लॉगिंग का उपयोग करें। प्रत्येक लॉन्च पर UserDefaults में एक फ़्लैग जोड़ें — यदि अगले स्टार्ट पर फ़्लैग गायब है, तो ऐप्लिकेशन अनुचित रूप से समाप्त किया गया था। Android पर, ActivityManager.isBackgroundRestricted() का उपयोग करें यह जाँचने के लिए कि क्या ऐप्लिकेशन बैकग्राउंड कार्य चला सकता है। साथ ही, onTrimMemory(TRIM_MEMORY_COMPLETE) की निगरानी करें — यह संकेत है कि प्रक्रिया समाप्त हो जाएगी।
पहला नियम — कभी यह न मानें कि applicationWillTerminate या onDestroy कॉल होंगे। Active से Background में प्रत्येक संक्रमण पर महत्वपूर्ण डेटा सहेजें। सरल सेटिंग्स के लिए की-वैल्यू स्टोर और संरचित डेटा के लिए SQLite/Room का उपयोग करें।
दूसरा नियम — कोल्ड स्टार्ट समय मापें और इसे अनुकूलित करें। आलसी आरंभीकरण, मुख्य थ्रेड में काम कम करना, संसाधनों को पूर्व-लोड करना, SplashScreen API का उपयोग — ये सभी लॉन्च समय की धारणा में सुधार करते हैं। Google अनुशंसा करता है उत्कृष्ट UX के लिए कोल्ड स्टार्ट 200 ms से कम हो।
तीसरा नियम — अवस्था पुनर्स्थापना लागू करें। iOS पर, UIApplication.stateRestorationIdentifier और NSUserActivity का उपयोग करें। Android पर, onSaveInstanceState के साथ संयुक्त ViewModel में SavedStateHandle का उपयोग करें। यह उपयोगकर्ता को ऐप पुनर्स्टार्ट के बाद उसी स्थान से काम जारी रखने की अनुमति देगा।
चौथा नियम — launchOptions और Intent को संभालें जिनके साथ ऐप्लिकेशन Not Running के बाद शुरू किया गया था। डीप लिंक, पुश नोटिफिकेशन, यूनिवर्सल लिंक — ये सभी लॉन्च पैरामीटर के माध्यम से पारित होते हैं। डेवलपर को इन डेटा को सही ढंग से निकालना चाहिए और उपयोगकर्ता को संबंधित स्क्रीन पर निर्देशित करना चाहिए।
// कोल्ड स्टार्ट के बाद डीप लिंक संभालना
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// जाँच करना कि नोटिफिकेशन आया या नहीं
if let notification = launchOptions?[.remoteNotification] as? [String: Any] {
handleNotification(notification)
}
// डीप लिंक जाँच
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)
}कोड iOS कोल्ड स्टार्ट पर लॉन्च पैरामीटर की हैंडलिंग दिखाता है। launchOptions में वह डेटा होता है जिसके साथ सिस्टम ने ऐप्लिकेशन लॉन्च किया। नोटिफिकेशन, डीप लिंक और यूनिवर्सल लिंक इस डिक्शनरी के माध्यम से पारित होते हैं। डेवलपर को एक सहज उपयोगकर्ता अनुभव सुनिश्चित करने के लिए सभी संभावित लॉन्च परिदृश्यों को सही ढंग से संभालना चाहिए।
अक्सर पूछे जाने वाले प्रश्न
स्थायी भंडारण (UserDefaults, Core Data, SharedPreferences, Room) में सहेजा गया डेटा संरक्षित रहता है। RAM में डेटा — चर, कैश, SavedStateHandle के बिना ViewModel अवस्था — अपरिवर्तनीय रूप से खो जाता है। इसलिए, प्रत्येक Background में संक्रमण पर ऐप्लिकेशन अवस्था सहेजना अत्यंत महत्वपूर्ण है।
कोल्ड स्टार्ट के दौरान, application(_:didFinishLaunchingWithOptions:) कॉल किया जाता है। हॉट स्टार्ट (Suspended से वापसी) के दौरान, यह विधि कॉल नहीं होती — केवल applicationWillEnterForeground और applicationDidBecomeActive सक्रिय होते हैं। यदि आपको केवल कोल्ड स्टार्ट पर कोई कार्रवाई करने की आवश्यकता है, तो didFinishLaunchingWithOptions में एक फ़्लैग सेट करें।
हाँ। स्थायी नोटिफिकेशन वाला Foreground Service सिस्टम को प्रक्रिया समाप्त करने से रोकता है, भले ही सभी Activities नष्ट हो गई हों। Background Service (बिना foreground के startService) को सिस्टम किसी भी समय रोक सकता है। चल रही Service का मतलब है कि प्रक्रिया मौजूद है, और यह अब Not Running नहीं है।
iOS सिम्युलेटर पर, App Switcher (Cmd+Shift+H दो बार, ऊपर स्वाइप) के माध्यम से ऐप समाप्त करें। Android एम्युलेटर पर, adb shell am force-stop com.example.app या Logcat में Stop बटन का उपयोग करें। उसके बाद, ऐप्लिकेशन को फिर से लॉन्च करें — यह Not Running से एक साफ कोल्ड स्टार्ट होगा।
Kill-switch आपातकालीन ऐप्लिकेशन समाप्ति के लिए एक सर्वर कमांड है। इसका उपयोग बैंकिंग और कॉर्पोरेट ऐप्लिकेशन में दूरस्थ पहुँच अवरोधन के लिए किया जाता है। यदि ऐप्लिकेशन को kill कमांड मिलता है, तो अगले कोल्ड स्टार्ट पर यह UI को ब्लॉक करता है और पुनः प्रमाणीकरण का अनुरोध करता है। iOS पर, kill-switch को ब्लॉकिंग फ़्लैग के साथ रिमोट नोटिफिकेशन के माध्यम से कार्यान्वित किया जाता है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें