Suspended — iOS ilovasining hayot siklidagi toʻxtatilgan holat, bunda ilova xotirada muzlatilgan, ammo kod bajarmaydi. Suspended qanday ishlashini, ilovani fonda muzlatish qanday xavflarni keltirishini, iOS Suspended ilovalarni tushirishni qanday boshqarishini va Suspended-dan qaytgandan soʻng muammosiz tiklanish uchun state restoration-ni qanday amalga oshirishni koʻrsatamiz.
Asosiy maʻlumotlar
Suspended — iOS ilovasining hayot siklidagi holat boʻlib, unda ilova qurilmaning operativ xotirasida joylashgan, lekin hech qanday kod bajarmaydi. Bu toʻliq tugatishdan oldingi oxirgi holat: ilova barcha fon vazifalarini tugatgandan soʻng yoki vaqt chegarasi tugagandan keyin Background-dan Suspended-ga oʻtadi. Suspended-da ilova butunlay muzlatilgan — barcha oqimlar toʻxtatilgan, taymerlar ishlamaydi, tarmoq faolligi yoʻq.
Suspended — Android-ning standart hayot siklida mavjud boʻlmagan noyob iOS xususiyati. Sababi jarayonlarni boshqarishning turli arxitekturasidir. iOS ilova tasvirini xotirada saqlaydi (desktopdagi hibernatsiyaga oʻxshab), foydalanuvchi qaytganda interfeysni sovuq startsiz darhol tiklash uchun. Android-da Suspended yoʻq — jarayon yoki mavjud va kod bajarishi mumkin (Background), yoki tugatilgan (Not Running), garchi Android LMK orqali oqimlarni toʻxtatishi mumkin.
Foydalanuvchi uchun Suspended bir zumda tiklash kabi koʻrinadi: u App Switcher orqali ilovalar oʻrtasida almashadi va har bir ilova uni tark etgan joydan ochiladi. Bu barcha ilovalar bir vaqtda ishlayotgandek tasavvur yaratadi. Aslida ularning koʻpchiligi Suspended-da muzlatilgan. Suspended-dan issiq start Not Running-dan sovuq startga qaraganda bir necha barobar tezroq, chunki kod allaqachon xotiraga yuklangan.
iOS barcha ilovalarning holatini kuzatadi va mavjud xotira asosida Suspended ilovalarni tushirish toʻgʻrisida qaror qabul qiladi. Xotira yetishmaganda, tizim Suspended ilovalarni tushira boshlaydi, eng uzoq vaqt ushbu holatda boʻlganlardan boshlab. Agar xotira hali ham yetishmasa, tizim ilovalarni Background va Inactive-dan Suspended-ga oʻtkazadi, soʻngra ularni tushiradi. Bu jarayon foydalanuvchi uchun butunlay shaffof — u faqat App Switcher-da ilova belgisini koʻradi, bosganda esa sovuq start ishga tushadi.
| Xususiyat | Suspended (iOS) | Background (iOS) | Background (Android) |
|---|---|---|---|
| Kod bajariladi | Yoʻq | Ha (cheklangan) | Ha (cheklangan) |
| Xotirada | Ha | Ha | Ha |
| CPU isteʻmoli | 0% | Past | Past |
| Issiq start | Ha — bir zumda tiklash | Ha — Inactive orqali | Yoʻq — jarayon oʻldirilgan boʻlishi mumkin |
| Vaqt chegarasi | Yoʻq — soatlab xotirada qolishi mumkin | ~30 soniya (beginBackgroundTask-dan keyin) | API versiyasiga bogʻliq |
| Tizim tomonidan tushirish | Xotira yetishmasa | Kritik xotira yetishmasa | LMK (Low Memory Killer) |
| Ishga qaytish | App Switcher-dan — darhol | App Switcher-dan — Inactive orqali | Sovuq start |
| State Restoration | Tavsiya etiladi | Talab qilinmaydi | SavedStateHandle |
iOS-da Suspended barcha fon vazifalari tugagandan soʻng avtomatik ravishda erishiladi. Tizim applicationDidEnterBackground-ni chaqiradi, beginBackgroundTask-ni bajarish uchun vaqt beradi (taxminan 30 soniya), soʻngra barcha oqimlarni majburan toʻxtatadi va ilovani Suspended holatiga oʻtkazadi. Xotiradagi obʻektlar saqlanadi, lekin hech qanday kod bajarilmaydi — ilova joriy holatda muzlatiladi.
Kritik muhim nuqta: applicationDidEnterBackground — Suspended-dan oldin kafolatlangan chaqiriladigan oxirgi metod. Shundan soʻng ilova xotiradan tushirilishi haqida hech qanday bildirishnoma olmaydi. Agar foydalanuvchi yoki tizim Suspended holatidagi ilovani oʻldirsa, na applicationWillTerminate, na qayta applicationDidEnterBackground chaqiriladi. Shuning uchun barcha maʻlumotlarni saqlash applicationDidEnterBackground-da, applicationWillTerminate-da emas, bajarilishi kerak.
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
// Suspended-dan oldin oxirgi kafolatlangan chaqiriq
func applicationDidEnterBackground(_ application: UIApplication) {
// Xotiradan tushirishdan omon qolishi kerak boʻlgan hamma narsani saqlaymiz
savePersistentState()
saveNavigationStack()
// Agar kerak boʻlsa, qoʻshimcha vaqt soʻraymiz
let task = application.beginBackgroundTask {
application.endBackgroundTask(task)
}
}
// Suspended-dan qaytish — issiq start
func applicationWillEnterForeground(_ application: UIApplication) {
// Ilova Suspended-da edi, ishga qaytamiz
print("Suspended yoki Background-dan qaytish")
}
// Xotiradan tushirishdan keyin toʻliq tiklash
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// Agar bu Suspended-dan tushirishdan keyin sovuq start boʻlsa —
// state restoration-ni tiklaymiz
return true
}
private func savePersistentState() {
UserDefaults.standard.set(Date(), forKey: "lastActiveDate")
}
private func saveNavigationStack() {
guard let rootVC = window?.rootViewController else { return }
// Joriy navigatsiya stekini saqlaymiz
if let navController = rootVC as? UINavigationController {
let vcClasses = navController.viewControllers.map { type(of: $0) }
UserDefaults.standard.set(vcClasses.map { NSStringFromClass($0) }, forKey: "navStack")
}
}
}Kod iOS-da Suspended-ni muhim qayta ishlashni koʻrsatadi. applicationDidEnterBackground — oxirgi kafolatlangan chaqiriq. Barcha maʻlumotlar saqlanishi bu yerda boʻlishi kerak: foydalanuvchi holati, navigatsiya steki, qoralamalar, taymerlar. applicationWillEnterForeground Suspended yoki Background-dan qaytganda chaqiriladi. didFinishLaunchingWithOptions — faqat sovuq startda, ilova Suspended-dan keyin xotiradan tushirilganda.
Android-da toʻgʻridan-toʻgʻri analogi yoʻq iOS Suspended uchun. Android ilovalarni bajarish kontekstini saqlab, xotirada muzlatmaydi. Buning oʻrniga Android yoki jarayonni fonda ushlab turadi (Background), yoki uni tugatadi (Not Running). Biroq Android 11+ (API 30) da App Freezer mexanizmi paydo boʻldi, u SIGSTOP signali yordamida fon jarayonlarini toʻxtatadi. Bu Suspended-ning funksional analogi, ammo muhim farqlar bilan.
App Freezer — Android xotira boshqaruvi tizimining bir qismi. Ilova uzoq vaqt fonda qolsa va faol bildirishnomalari boʻlmasa, tizim unga SIGSTOP yuboradi, barcha oqimlarni toʻxtatadi. Ilova oldingi planga qaytganda SIGCONT yuboriladi va bajarish davom etadi. iOS-dan asosiy farq: App Freezer holatni saqlashni kafolatlamaydi — muzlatish vaqtida jarayon oʻldirilsa, xotiradagi maʻlumotlar yoʻqolishi mumkin.
Android-da SavedStateHandle dan foydalanish tavsiya etiladi ViewModel-da har qanday jarayon tugashida avtomatik holatni saqlash uchun. SavedStateHandle maʻlumotlarni Bundle-da onSaveInstanceState orqali saqlaydi, bu ham App Freezer, ham Process Death-dan omon qoladi. iOS-dan farqli oʻlaroq, bu yerda Suspended-dan tushirish istisno holat, Android-da Process Death oddiy xatti-harakat boʻlib, har doim kutilishi kerak.
// SavedStateHandle — Android-da Process Death-dan qutulish
class CheckoutViewModel(
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
// App Freezer-dan keyin ham jarayondan omon qoladigan holat
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 holati uchun onStop-da saqlash
class MainActivity : AppCompatActivity() {
override fun onStop() {
super.onStop()
// Muzlatishdan omon qolishi kerak boʻlgan maʻlumotlarni saqlaymiz
saveDraftData()
// Muzlatilgan holatda kerak boʻlmagan resurslarni boʻshatamiz
releaseHeavyResources()
// Ilova muzlatilishi haqida ogohlantiramiz
// (Disk raskadrovka uchun jurnal)
Log.d("Lifecycle", "Activity toʻxtatildi — mumkin App Freeze")
}
}Kod Android-da Suspended analogini qayta ishlash yondashuvini koʻrsatadi. SavedStateHandle ViewModel-da Process Death vaqtida avtomatik maʻlumotlarni saqlaydi va tiklaydi. onStop — mumkin boʻlgan App Freezer yoki jarayon tugashidan oldin oxirgi kafolatlangan hodisa. Buyurtma formasi holati, savatdagi mahsulotlar roʻyxati — barcha bu maʻlumotlar SavedStateHandle tufayli muzlatishdan omon qoladi. Ogʻir resurslar uchun (bitmaplar, maʻlumotlar bazasi kursorlari) onStop xotirani boʻshatish joyidir.
State Restoration — ilova xotiradan tushirilgandan keyin UI holatini saqlash va tiklash uchun iOS-ning ichki mexanizmi. Agar ilova Suspended-da boʻlib, tizim uni tushirgan boʻlsa, keyingi sovuq startda state restoration navigatsiya stekini, aylantirish pozitsiyasini, formalar holatini va boshqa UI elementlarini tiklaydi. Foydalanuvchi toʻxtagan ekranga qaytadi.
State Restoration UIViewControllerRestoration va UIStateRestoring protokollari orqali ishlaydi. Dasturchi tiklamoqchi boʻlgan har bir ViewController va View-ga restorationIdentifier tayinlaydi. Background-ga oʻayotganda iOS ushbu obʻektlarning holatini kodlaydi. Tushirishdan qaytgach, iOS yangi obʻektlar yaratadi va saqlangan holatni dekodlaydi. State restoration boʻlmasa, foydalanuvchi sovuq startdan keyin toʻxtagan joyi oʻrniga boʻsh ekranni koʻradi.
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
// Maʻlumotlar yuklangandan soʻng pozitsiyani tiklaymiz
}
}
}
// AppDelegate — State Restoration-ni faollashtirish
func application(
_ application: UIApplication,
shouldSaveSecureApplicationState coder: NSCoder
) -> Bool {
return true
}
func application(
_ application: UIApplication,
shouldRestoreSecureApplicationState coder: NSCoder
) -> Bool {
return true
}Kod iOS-da State Restoration amalga oshirilishini koʻrsatadi. restorationIdentifier va restorationClass har bir tiklanadigan ViewController uchun zarur. encodeRestorableState/decodeRestorableState NSCoder orqali maʻlumotlarni saqlaydi va yuklaydi. AppDelegate-da shouldSaveSecureApplicationState va shouldRestoreSecureApplicationState shifrlangan holatni saqlashni yoqadi. iOS 12+ dan maʻlumotlarni himoya qilish uchun secure encoding (NSSecureCoding) dan foydalanish tavsiya etiladi.
Birinchi qoida — hech qachon ilova Suspended-dan qaytadi deb hisoblamang. Tizim istalgan vaqtda ilovani tushirishi mumkin. Barcha kritik muhim maʻlumotlar Suspended-ga oʻtishdan oldin — yaʻni applicationDidEnterBackground yoki onStop-da — doimiy xotirada saqlanishi kerak. UserDefaults, Core Data, File Manager — mos xotiralar. Xotira (oʻzgaruvchilar, xususiyatlar) Suspended-dan omon qolishi kerak boʻlgan maʻlumotlar uchun ishonchsiz xotiradir.
Ikkinchi qoida — Suspended-dan oldin resurslarni boʻshating. Fayl deskriptorlarini yoping, GPU xotirasini (Metal, Core Graphics) boʻshating, tarmoq ulanishlarini yoping. Ilova Suspended-da CPU isteʻmol qilmasa ham, band qilingan resurslar boshqa ilovalar uchun bloklanadi. iOS-da Suspended-da ochiq soketlarni saqlash mumkin emas — Suspended-dan qaytganda ular ishlamasligi mumkin, bu xatolarga olib keladi.
Uchinchi qoida — Suspended-dan qaytishni kutadigan vaqtga bogʻliq mantiqni joylashtirmang. Taymerlar, callback-lar va tarmoq faolligi Suspended-da toʻxtaydi. Agar ilova bir necha soat Suspended-da boʻlsa, qaytganda taymer notoʻgʻri ishlashi mumkin. Qaytganda maʻlumotlarning dolzarbligini tekshiring — ehtimol kesh eskirgan, avtorizatsiya tokeni muddati oʻtgan.
Toʻrtinchi qoida — barcha ekranlar uchun State Restoration-dan foydalaning, ayniqsa kiritish formalari, aylantiriladigan roʻyxatlar va batafsil ekranlar uchun. State restoration boʻlmasa, foydalanuvchi tushirilgan Suspended-dan qaytgach, toʻxtagan joyi oʻrniga ilovaning boshlangʻich ekranini koʻradi. Bu foydalanuvchi tajribasini yomonlashtiradi va uni harakatlarni takrorlashga majbur qiladi.
import UIKit
// Tekshirish: ilova xotiradan tushirilganmi?
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// Saqlangan holat mavjudligini tekshiramiz
if UserDefaults.standard.object(forKey: "navStack") != nil {
// Ilova Suspended-dan tushirilgan
// Holatni tiklash kerak
restoreNavigationStack()
} else {
// Not Running-dan toza sovuq start
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)
}
}
}Kod ilovaning Suspended-dan tushirilganligini aniqlash amaliyotini koʻrsatadi. UserDefaults-ni tekshirish saqlangan navigatsiya stekining mavjudligiga qarab tushirishdan keyingi sovuq startni toza sovuq startdan farqlash imkonini beradi. Birinchi holatda navigatsiya steki tiklanadi, ikkinchisida — onboarding yoki asosiy ekran koʻrsatiladi. Ushbu yondashuv NSCoder yetarli boʻlmagan hollarda oʻrnatilgan State Restoration-ni toʻldiradi.
Koʻp beriladigan savollar
Cheklanmagan — bir necha soniyadan bir necha kungacha. iOS-da Suspended uchun vaqt chegarasi yoʻq. Ilova tizim resurs yetishmasligi sababli uni tushirishga qaror qilmaguncha xotirada qoladi. Amaliyotda ilovalar qurilmaning RAM hajmi va faol ilovalar soniga qarab 15 daqiqadan bir necha soatgacha Suspended-da qoladi.
Yoʻq. applicationWillTerminate chaqirilmaydi ilova Suspended-dan tushirilganda. Tizim shunchaki ilovani xabardor qilmasdan xotirani boʻshatadi. Bu barcha maʻlumotlarni saqlash applicationDidEnterBackground-da boʻlishining yana bir sababidir. applicationWillTerminate faqat foydalanuvchi ilovani App Switcher-dan sudrab olib qoʻlda tugatganda chaqiriladi.
Toʻgʻridan-toʻgʻri analogi yoʻq. Android 11+ da App Freezer paydo boʻldi, u SIGSTOP orqali fon jarayonlarini toʻxtatadi — bu funksional jihatdan Suspended-ga oʻxshaydi. Biroq Android ilovalari istalgan vaqtda Process Death ni hisobga olgan holda loyihalashtirilishi kerak. ViewModel-da SavedStateHandle va onSaveInstanceState-dan foydalaning, bu holatni ham App Freezer, ham Process Death-dan omon qoldiradi.
iOS-da toʻgʻridan-toʻgʻri tekshirish API-i yoʻq. Bilvosita usul: UserDefaults-ni tekshiring didFinishLaunchingWithOptions-da saqlangan holat mavjudligiga. Agar holat mavjud boʻlsa — ilova Suspended-dan tushirilgan va sovuq start qilmoqda. Agar holat boʻlmasa — toza sovuq start. SwiftUI-da scenePhase.background-da flag saqlab, keyingi ishga tushirishda tekshirishingiz mumkin.
Suspended-ga oʻtganda iOS snapshot — ilovaning joriy UI ekran tasvirini oladi. Bu tasvir App Switcher-da va ilovaga qaytganda (erish animatsiyasi sifatida) koʻrsatiladi. Agar ilova maxfiy maʻlumotlarni oʻz ichiga olgan boʻlsa, snapshot ularni oshkor qilishi mumkin. Himoya uchun UIApplication.shouldSnapshotSecureApp (iOS 16+) dan foydalaning yoki applicationDidEnterBackground-da blur-overlay qoʻying.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.