Suspended — iOS ऐप जीवनचक्र की एक रुकी हुई स्थिति जिसमें ऐप मेमोरी में फ़्रीज़ होता है लेकिन कोड निष्पादित नहीं करता। हम दिखाते हैं कि Suspended कैसे काम करता है, पृष्ठभूमि में ऐप फ़्रीज़ होने के क्या जोखिम हैं, iOS Suspended ऐप्स को अनलोड कैसे करता है, और Suspended से लौटने के बाद निर्बाध पुनर्प्राप्ति के लिए state restoration कैसे लागू करें।
मुख्य बातें
Suspended iOS ऐप जीवनचक्र की एक स्थिति है जिसमें ऐप डिवाइस की RAM में रहता है लेकिन कोई कोड निष्पादित नहीं करता। यह पूर्ण समाप्ति से पहले की अंतिम स्थिति है: ऐप सभी पृष्ठभूमि कार्यों को पूरा करने या टाइमआउट समाप्त होने के बाद Background से Suspended में संक्रमण करता है। Suspended में, ऐप पूरी तरह से फ़्रीज़ होता है — सभी थ्रेड रुके हुए हैं, टाइमर काम नहीं करते, और कोई नेटवर्क गतिविधि नहीं होती।
Suspended iOS की एक अनूठी विशेषता है, जो मानक Android जीवनचक्र में अनुपस्थित है। इसका कारण अलग प्रक्रिया प्रबंधन आर्किटेक्चर में निहित है। iOS ऐप की छवि को मेमोरी में संरक्षित करता है (डेस्कटॉप हाइबरनेशन के समान) ताकि जब उपयोगकर्ता लौटे, तो इंटरफ़ेस बिना कोल्ड स्टार्ट के तुरंत पुनर्स्थापित हो सके। Android में Suspended नहीं है — एक प्रक्रिया या तो मौजूद है और कोड निष्पादित कर सकती है (Background) या समाप्त हो गई है (Not Running), हालाँकि Android LMK के माध्यम से थ्रेड निष्पादन को रोक सकता है।
उपयोगकर्ता के लिए, Suspended तत्काल पुनर्स्थापना जैसा दिखता है: वे App Switcher के माध्यम से ऐप्स के बीच स्विच करते हैं, और प्रत्येक ऐप वहीं खुलता है जहाँ उन्होंने छोड़ा था। यह भ्रम पैदा करता है कि सभी ऐप्स एक साथ चल रहे हैं। वास्तव में, उनमें से अधिकांश Suspended में फ़्रीज़ हैं। Suspended से हॉट स्टार्ट Not Running से कोल्ड स्टार्ट की तुलना में कई गुना तेज़ है, क्योंकि कोड पहले से मेमोरी में लोड है।
iOS सभी ऐप्स की स्थिति पर नज़र रखता है और उपलब्ध मेमोरी के आधार पर Suspended ऐप्स को अनलोड करने का निर्णय लेता है। जब मेमोरी कम होती है, तो सिस्टम Suspended ऐप्स को अनलोड करना शुरू करता है, उनसे शुरू करता है जो इस स्थिति में सबसे लंबे समय से हैं। यदि मेमोरी अभी भी अपर्याप्त है, तो सिस्टम ऐप्स को Background और Inactive से Suspended में बाद के अनलोड के साथ संक्रमण करता है। यह प्रक्रिया उपयोगकर्ता के लिए पूरी तरह से पारदर्शी है — वे बस App Switcher में ऐप आइकन देखते हैं, जो टैप करने पर कोल्ड स्टार्ट शुरू करता है।
| विशेषता | Suspended (iOS) | Background (iOS) | Background (Android) |
|---|---|---|---|
| कोड निष्पादित होता है | नहीं | हाँ (सीमित) | हाँ (सीमित) |
| मेमोरी में | हाँ | हाँ | हाँ |
| CPU खपत | 0% | कम | कम |
| हॉट स्टार्ट | हाँ — तत्काल पुनर्स्थापना | हाँ — Inactive के माध्यम से | नहीं — प्रक्रिया समाप्त हो सकती है |
| टाइमआउट | नहीं — घंटों मेमोरी में रह सकता है | ~30 सेकंड (beginBackgroundTask के बाद) | API संस्करण पर निर्भर करता है |
| सिस्टम द्वारा अनलोड | मेमोरी कम होने पर | गंभीर मेमोरी कमी पर | LMK (Low Memory Killer) |
| काम पर वापसी | App Switcher से — तुरंत | App Switcher से — Inactive के माध्यम से | कोल्ड स्टार्ट |
| State Restoration | अनुशंसित | आवश्यक नहीं | SavedStateHandle |
iOS में, सभी पृष्ठभूमि कार्यों को पूरा करने के बाद Suspended स्वचालित रूप से प्राप्त होता है। सिस्टम applicationDidEnterBackground को कॉल करता है, beginBackgroundTask को निष्पादित करने का समय देता है (लगभग 30 सेकंड), फिर जबरदस्ती सभी थ्रेड को रोकता है और ऐप को Suspended में स्थानांतरित करता है। मेमोरी में ऑब्जेक्ट संरक्षित रहते हैं, लेकिन कोई कोड निष्पादित नहीं होता — ऐप अपनी वर्तमान स्थिति में फ़्रीज़ होता है।
एक अत्यंत महत्वपूर्ण बिंदु: applicationDidEnterBackground अंतिम विधि है जो Suspended से पहले गारंटीकृत रूप से कॉल की जाती है। इसके बाद, ऐप को मेमोरी अनलोड के बारे में कोई सूचना नहीं मिलती। यदि उपयोगकर्ता या सिस्टम Suspended में ऐप को समाप्त करता है, तो न तो applicationWillTerminate और न ही applicationDidEnterBackground फिर से कॉल किया जाता है। इसलिए, सभी डेटा सेविंग applicationDidEnterBackground में होनी चाहिए, applicationWillTerminate में नहीं।
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
// Suspended से पहले अंतिम गारंटीकृत कॉल
func applicationDidEnterBackground(_ application: UIApplication) {
// वह सब कुछ सहेजें जिसे मेमोरी अनलोड से बचना है
savePersistentState()
saveNavigationStack()
// यदि आवश्यक हो तो अतिरिक्त समय का अनुरोध करें
let task = application.beginBackgroundTask {
application.endBackgroundTask(task)
}
}
// Suspended से वापसी — हॉट स्टार्ट
func applicationWillEnterForeground(_ application: UIApplication) {
// ऐप Suspended में था, काम फिर से शुरू करना
print("Suspended या Background से वापसी")
}
// मेमोरी अनलोड के बाद पूर्ण पुनर्स्थापना
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// यदि यह Suspended से अनलोड के बाद कोल्ड स्टार्ट है —
// state restoration पुनर्स्थापित करें
return true
}
private func savePersistentState() {
UserDefaults.standard.set(Date(), forKey: "lastActiveDate")
}
private func saveNavigationStack() {
guard let rootVC = window?.rootViewController else { return }
// वर्तमान नेविगेशन स्टैक सहेजें
if let navController = rootVC as? UINavigationController {
let vcClasses = navController.viewControllers.map { type(of: $0) }
UserDefaults.standard.set(vcClasses.map { NSStringFromClass($0) }, forKey: "navStack")
}
}
}कोड iOS पर Suspended की अत्यंत महत्वपूर्ण हैंडलिंग दिखाता है। applicationDidEnterBackground अंतिम गारंटीकृत कॉल है। सभी डेटा सेविंग यहाँ होनी चाहिए: उपयोगकर्ता स्थिति, नेविगेशन स्टैक, ड्राफ्ट, टाइमर। applicationWillEnterForeground Suspended या Background से लौटने पर कॉल किया जाता है। didFinishLaunchingWithOptions — केवल कोल्ड स्टार्ट पर, जब ऐप को Suspended के बाद मेमोरी से अनलोड किया गया था।
Android में, iOS Suspended का कोई सीधा एनालॉग नहीं है। Android निष्पादन संदर्भ को संरक्षित करते हुए ऐप्स को मेमोरी में फ़्रीज़ नहीं करता। इसके बजाय, Android या तो प्रक्रिया को पृष्ठभूमि में रखता है या उसे समाप्त करता है। हालाँकि, Android 11+ (API 30) पर App Freezer नामक एक तंत्र पेश किया गया, जो SIGSTOP सिग्नल का उपयोग करके पृष्ठभूमि प्रक्रियाओं के निष्पादन को रोकता है। यह कार्यात्मक रूप से Suspended के समान है, लेकिन महत्वपूर्ण अंतरों के साथ।
App Freezer Android मेमोरी प्रबंधन प्रणाली का हिस्सा है। जब कोई ऐप बिना सक्रिय सूचनाओं के लंबे समय तक पृष्ठभूमि में रहता है, तो सिस्टम उसे SIGSTOP भेजता है, सभी थ्रेड को रोकता है। जब ऐप अग्रभूमि में लौटता है, तो SIGCONT भेजा जाता है और निष्पादन फिर से शुरू होता है। iOS से मुख्य अंतर: App Freezer स्थिति संरक्षण की गारंटी नहीं देता — यदि फ़्रीज़िंग के दौरान प्रक्रिया समाप्त हो जाती है तो मेमोरी में डेटा खो सकता है।
Android पर, किसी भी प्रक्रिया समाप्ति के दौरान स्वचालित स्थिति संरक्षण के लिए ViewModel में SavedStateHandle का उपयोग करने की अनुशंसा की जाती है। SavedStateHandle onSaveInstanceState के माध्यम से Bundle में डेटा सहेजता है, जो App Freezer और Process Death दोनों से बच जाता है। iOS के विपरीत, जहाँ Suspended से अनलोड एक असाधारण स्थिति है, Android पर Process Death सामान्य व्यवहार है जिसकी हमेशा उम्मीद की जानी चाहिए।
// SavedStateHandle — Android पर Process Death से मुक्ति
class CheckoutViewModel(
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
// स्थिति जो App Freezer के बाद भी प्रक्रिया से बच जाती है
var currentStep: MutableLiveData<Int> =
savedStateHandle.getLiveData("checkout_step", 1)
var cartItems: MutableLiveData<List<CartItem>> =
savedStateHandle.getLiveData("cart_items", emptyList())
fun proceedToNextStep() {
currentStep.value = (currentStep.value ?: 0) + 1
}
fun addToCart(item: CartItem) {
val updatedList = (cartItems.value ?: emptyList()) + item
cartItems.value = updatedList
savedStateHandle["cart_items"] = updatedList
}
}
// App Freezer की स्थिति में onStop में सहेजें
class MainActivity : AppCompatActivity() {
override fun onStop() {
super.onStop()
// डेटा सहेजें जिसे फ़्रीज़िंग से बचना चाहिए
saveDraftData()
// जमी हुई स्थिति में आवश्यक नहीं संसाधनों को मुक्त करें
releaseHeavyResources()
// चेतावनी दें कि ऐप फ़्रीज़ हो जाएगा
// (डिबगिंग के लिए लॉगिंग)
Log.d("Lifecycle", "Activity stopped — संभावित App Freeze")
}
}कोड Android पर Suspended एनालॉग को संभालने का दृष्टिकोण दिखाता है। ViewModel में SavedStateHandle Process Death के दौरान स्वचालित रूप से डेटा सहेजता और पुनर्स्थापित करता है। onStop संभावित App Freezer या प्रक्रिया समाप्ति से पहले अंतिम गारंटीकृत घटना है। चेकआउट फ़ॉर्म स्थिति, कार्ट आइटम सूची — ये सभी डेटा SavedStateHandle की बदौलत फ़्रीज़िंग से बच जाते हैं। भारी संसाधनों (बिटमैप, DB कर्सर) के लिए, onStop मेमोरी मुक्त करने का स्थान है।
State Restoration iOS का एक अंतर्निर्मित तंत्र है जो ऐप को मेमोरी से अनलोड करने के बाद UI स्थिति को सहेजने और पुनर्स्थापित करने के लिए है। यदि ऐप Suspended में था और सिस्टम ने उसे अनलोड कर दिया, तो अगले कोल्ड स्टार्ट पर state restoration नेविगेशन स्टैक, स्क्रॉल स्थिति, फ़ॉर्म स्थिति और अन्य UI तत्वों को पुनर्स्थापित करता है। उपयोगकर्ता उसी स्क्रीन पर लौटता है जहाँ उसने छोड़ा था।
State Restoration UIViewControllerRestoration और UIStateRestoring प्रोटोकॉल के माध्यम से काम करता है। डेवलपर प्रत्येक ViewController और View को restorationIdentifier निर्दिष्ट करता है जिसे वे पुनर्स्थापित करना चाहते हैं। पृष्ठभूमि में जाने पर, iOS इन ऑब्जेक्ट्स की स्थिति को एन्कोड करता है। अनलोड के बाद लौटने पर, iOS नए ऑब्जेक्ट बनाता है और सहेजी गई स्थिति को डिकोड करता है। State restoration के बिना, उपयोगकर्ता कोल्ड स्टार्ट के बाद एक खाली स्क्रीन दिखाई देगी जहाँ उसने छोड़ा था, उसके बजाय।
import UIKit
class DetailViewController: UIViewController {
var itemID: String = ""
var scrollPosition: CGPoint = .zero
override func viewDidLoad() {
super.viewDidLoad()
restorationIdentifier = "DetailViewController"
restorationClass = type(of: self)
}
override func encodeRestorableState(with coder: NSCoder) {
super.encodeRestorableState(with: coder)
coder.encode(itemID, forKey: "itemID")
coder.encode(scrollPosition, forKey: "scrollPosition")
}
override func decodeRestorableState(with coder: NSCoder) {
super.decodeRestorableState(with: coder)
if let savedID = coder.decodeObject(forKey: "itemID") as? String {
itemID = savedID
loadItem()
}
if let savedPosition = coder.decodeCGPoint(forKey: "scrollPosition") {
scrollPosition = savedPosition
// डेटा लोड करने के बाद स्थिति पुनर्स्थापित करें
}
}
}
// AppDelegate — State Restoration सक्रिय करना
func application(
_ application: UIApplication,
shouldSaveSecureApplicationState coder: NSCoder
) -> Bool {
return true
}
func application(
_ application: UIApplication,
shouldRestoreSecureApplicationState coder: NSCoder
) -> Bool {
return true
}कोड iOS पर State Restoration के कार्यान्वयन को दिखाता है। प्रत्येक पुनर्स्थापनीय ViewController के लिए restorationIdentifier और restorationClass आवश्यक हैं। encodeRestorableState/decodeRestorableState NSCoder के माध्यम से डेटा सहेजते और लोड करते हैं। AppDelegate में, shouldSaveSecureApplicationState और shouldRestoreSecureApplicationState एन्क्रिप्टेड स्थिति संरक्षण को सक्षम करते हैं। iOS 12+ पर, डेटा सुरक्षा के लिए सुरक्षित एन्कोडिंग (NSSecureCoding) का उपयोग करने की अनुशंसा की जाती है।
पहला नियम — कभी यह मत मानें कि ऐप Suspended से लौटेगा। सिस्टम किसी भी क्षण ऐप को अनलोड कर सकता है। सभी अत्यंत महत्वपूर्ण डेटा Suspended में संक्रमण से पहले स्थायी भंडारण में सहेजा जाना चाहिए — यानी applicationDidEnterBackground या onStop में। UserDefaults, Core Data, File Manager — उपयुक्त भंडारण विकल्प। मेमोरी (चर, गुण) उन डेटा के लिए अविश्वसनीय भंडारण है जिन्हें Suspended से बचना चाहिए।
दूसरा नियम — Suspended से पहले संसाधनों को मुक्त करें। फ़ाइल डिस्क्रिप्टर बंद करें, GPU मेमोरी (Metal, Core Graphics) मुक्त करें, नेटवर्क कनेक्शन बंद करें। हालाँकि ऐप Suspended में CPU का उपभोग नहीं करता, लेकिन रखे गए संसाधन अन्य ऐप्स के लिए अवरुद्ध होते हैं। iOS पर, Suspended में खुले सॉकेट नहीं रखे जा सकते — Suspended से लौटने पर वे गैर-कार्यात्मक हो सकते हैं, जिससे त्रुटियाँ होती हैं।
तीसरा नियम — Suspended से लौटने की प्रतीक्षा में समय-निर्भर तर्क न रखें। टाइमर, कॉलबैक और नेटवर्क गतिविधि Suspended में समाप्त हो जाती है। यदि ऐप कई घंटों के लिए Suspended में था, तो लौटने पर एक टाइमर गलत तरीके से सक्रिय हो सकता है। लौटने पर डेटा की वैधता जाँचें — कैश पुराना हो सकता है, और प्राधिकरण टोकन समाप्त हो सकता है।
चौथा नियम — सभी स्क्रीनों के लिए State Restoration का उपयोग करें, विशेष रूप से इनपुट फ़ॉर्म, स्क्रॉल करने योग्य सूचियों और विवरण स्क्रीन के लिए। State restoration के बिना, अनलोड किए गए Suspended से लौटने के बाद, उपयोगकर्ता वहाँ के बजाय ऐप की प्रारंभिक स्क्रीन देखेगा जहाँ उसने छोड़ा था। यह उपयोगकर्ता अनुभव को ख़राब करता है और उपयोगकर्ता को कार्यों को दोहराने के लिए मजबूर करता है।
import UIKit
// जाँच: क्या ऐप मेमोरी से अनलोड किया गया था?
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// जाँचें कि सहेजी गई स्थिति मौजूद है या नहीं
if UserDefaults.standard.object(forKey: "navStack") != nil {
// ऐप Suspended से अनलोड किया गया था
// स्थिति पुनर्स्थापित करने की आवश्यकता है
restoreNavigationStack()
} else {
// Not Running से साफ कोल्ड स्टार्ट
showOnboardingIfNeeded()
}
return true
}
private func restoreNavigationStack() {
guard let savedStack = UserDefaults.standard.array(forKey: "navStack") as? [String],
let navController = window?.rootViewController as? UINavigationController
else { return }
for vcClassName in savedStack {
if let vcClass = NSClassFromString(vcClassName) as? UIViewController.Type {
let vc = vcClass.init()
navController.pushViewController(vc, animated: false)
}
}
}कोड यह निर्धारित करने का अभ्यास दिखाता है कि क्या ऐप को Suspended से अनलोड किया गया था। सहेजे गए नेविगेशन स्टैक की उपस्थिति के लिए UserDefaults की जाँच अनलोड के बाद कोल्ड स्टार्ट को साफ कोल्ड स्टार्ट से अलग करने की अनुमति देती है। पहले मामले में, नेविगेशन स्टैक पुनर्स्थापित किया जाता है; दूसरे में, ऑनबोर्डिंग या मुख्य स्क्रीन दिखाई जाती है। यह दृष्टिकोण उन मामलों के लिए अंतर्निर्मित State Restoration को पूरक करता है जहाँ NSCoder अपर्याप्त है।
अक्सर पूछे जाने वाले प्रश्न
असीमित — कुछ सेकंड से लेकर कई दिनों तक। iOS के पास Suspended के लिए कोई टाइमआउट नहीं है। ऐप तब तक मेमोरी में रहेगा जब तक सिस्टम संसाधनों की कमी के कारण उसे अनलोड करने का निर्णय नहीं लेता। व्यवहार में, ऐप डिवाइस की RAM और सक्रिय ऐप्स की संख्या के आधार पर 15 मिनट से लेकर कई घंटों तक Suspended में रहते हैं।
नहीं। Suspended से ऐप अनलोड करने पर applicationWillTerminate कॉल नहीं किया जाता। सिस्टम बस ऐप को सूचित किए बिना मेमोरी मुक्त करता है। यह एक और कारण है कि सभी डेटा सेविंग applicationDidEnterBackground में होनी चाहिए। applicationWillTerminate केवल तब कॉल किया जाता है जब उपयोगकर्ता ऐप को App Switcher से स्वाइप करके मैन्युअल रूप से समाप्त करता है।
कोई सीधा एनालॉग नहीं है। Android 11+ पर, App Freezer पेश किया गया, जो SIGSTOP के माध्यम से पृष्ठभूमि प्रक्रियाओं को रोकता है — यह कार्यात्मक रूप से Suspended के समान है। हालाँकि, Android ऐप्स को किसी भी क्षण Process Death मानकर डिज़ाइन किया जाना चाहिए। स्थिति को सहेजने के लिए ViewModel में SavedStateHandle और onSaveInstanceState का उपयोग करें जो App Freezer और Process Death दोनों से बचेगी।
iOS में जाँच के लिए कोई सीधा API नहीं है। एक अप्रत्यक्ष विधि: didFinishLaunchingWithOptions में सहेजी गई स्थिति की उपस्थिति के लिए UserDefaults की जाँच करें। यदि स्थिति मौजूद है — ऐप Suspended से अनलोड किया गया था और कोल्ड स्टार्ट कर रहा है। यदि स्थिति मौजूद नहीं है — साफ कोल्ड स्टार्ट। SwiftUI में, scenePhase.background में एक फ़्लैग सहेजा जा सकता है और अगले लॉन्च पर जाँचा जा सकता है।
Suspended में संक्रमण करते समय, iOS एक स्नैपशॉट लेता है — वर्तमान ऐप UI का स्क्रीनशॉट। यह स्क्रीनशॉट App Switcher में और ऐप पर लौटने पर (“पिघलना” एनिमेशन के रूप में) दिखाया जाता है। यदि ऐप में गोपनीय डेटा है, तो स्नैपशॉट उसे उजागर कर सकता है। सुरक्षा के लिए, UIApplication.shouldSnapshotSecureApp (iOS 16+) का उपयोग करें या applicationDidEnterBackground में ब्लर ओवरले लागू करें।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें