اہم نکات
App Lifecycle ایک محدود ریاست مشین ہے جو موبائل ایپلیکیشن کی تمام ممکنہ ریاستوں اور ان کے درمیان تبدیلیوں کو بیان کرتی ہے۔ ہر ریاست یہ طے کرتی ہے کہ آیا ایپ کوڈ چلا سکتی ہے، یوزر انٹرفیس دکھا سکتی ہے اور وسائل استعمال کر سکتی ہے۔ iOS اور Android کے ایک جیسے لیکن ایک جیسے نہیں ماڈل ہیں — فرق OS آرکیٹیکچر کی وجہ سے ہیں: iOS سخت میموری کنٹرول (suspended ریاست) استعمال کرتا ہے، جبکہ Android onSaveInstanceState کے ذریعے لچکدار عمل کا انتظام استعمال کرتا ہے۔
iOS میں، زندگی کا دور پیش منظر/پس منظر سے مضبوطی سے جڑا ہوا ہے: ایپ یا تو فعال ہے یا معطل۔ Android میں، زندگی کا دور زیادہ دانے دار ہے — ایک Activity/ونڈو 6+ ریاستوں سے گزرتی ہے، اور عمل خود ProcessLifecycleOwner کے ذریعے ایک اضافی زندگی کا دور رکھتا ہے۔ جدید ایپلیکیشنز (2024 سے) تیزی سے زندگی کے دور پر مبنی آرکیٹیکچر پیٹرن استعمال کر رہی ہیں: SwiftUI Lifecycle (iOS 16+) .scenePhase ماحول کے ذریعے، Compose Lifecycle LifecycleEventObserver کے ذریعے۔ یہ پیٹرن خود بخود سیاق و سباق کی تبدیلی کو سنبھالتے ہیں اور میموری لیک کو روکتے ہیں۔ Google کے مطابق، Android میں زندگی کے دور کی مناسب ہینڈلنگ پس منظر کے کام کے دوران میموری کی کھپت کو 30–40 % کم کرتی ہے۔
iOS میں، ایپ کا زندگی کا دور UIApplicationDelegate کلاس (AppDelegate) کے ذریعے منظم کیا جاتا ہے۔ اہم طریقے: application(_:didFinishLaunchingWithOptions:) — پہلے لانچ پر ابتداء؛ applicationDidBecomeActive — ایپ دکھائی دیتی ہے اور تعامل کے لیے تیار؛ applicationWillResignActive — غیر فعال حالت میں منتقلی (آنے والی کال، نوٹیفکیشن شیڈ بند کرنا)؛ applicationDidEnterBackground — ایپ چھپی ہوئی، ڈیٹا محفوظ کرنے کے لیے ~5 سیکنڈ؛ applicationWillEnterForeground — پس منظر سے واپسی؛ applicationWillTerminate — اختتام (صرف پرانی ایپ کے لیے بغیر suspended کے کال کیا جاتا ہے)۔
iOS 13 سے شروع کرتے ہوئے، Apple نے iPad اور macOS Catalyst پر کھڑکیوں والی ایپلیکیشنز کو سپورٹ کرنے کے لیے SceneDelegate (UISceneDelegate) متعارف کرایا۔ SceneDelegate ہر انفرادی منظر (ونڈو) کے زندگی کے دور کا انتظام کرتا ہے: scene(_:willConnectTo:options:) — منظر کی تخلیق؛ sceneDidBecomeActive — منظر فعال؛ sceneWillResignActive — منظر فوکس کھوتا ہے؛ sceneDidEnterBackground — منظر چھپا ہوا۔ AppDelegate عالمی واقعات (ڈیٹا لوڈنگ، پش نوٹیفکیشن) کو سنبھالتا ہے، جبکہ SceneDelegate ہر ونڈو کے یوزر انٹرفیس کی حالت کو سنبھالتا ہے۔ SwiftUI میں، زندگی کا دور @Environment(\.scenePhase): .active، .inactive، .background ماحولی قدر کے ذریعے سنبھالا جاتا ہے — یہ SwiftUI اور UIKit ایپلیکیشنز دونوں کے لیے ایک متحد API فراہم کرتا ہے۔
Android میں، زندگی کا دور Application کلاس سے شروع ہوتا ہے — ایک سنگلٹن جو کسی بھی Activity سے پہلے بنایا جاتا ہے۔ Application.onCreate() طریقہ پہلا داخلہ نقطہ ہے، جو عالمی ابتداء (Analytics، DI، Crash Reporting) کے لیے استعمال ہوتا ہے۔ اس کے بعد، Activity ترتیب کے ساتھ لانچ ہوتی ہے: onCreate() → onStart() → onResume()۔ چھوٹا کرنے پر: onPause() → onStop() → onSaveInstanceState()۔ تباہ ہونے پر: onDestroy()۔ واپسی پر: onRestart() → onStart() → onResume()۔
ProcessLifecycleOwner (AndroidX Lifecycle 2.2+ سے) پورے عمل کے زندگی کے دور کو ٹریک کرتا ہے، نہ کہ کسی انفرادی Activity کا۔ یہ دو حالتیں فراہم کرتا ہے: ON_RESUME (ایپ پیش منظر میں) اور ON_STOP (ایپ چھپی ہوئی)۔ ProcessLifecycleOwner عمل کی سطح پر «ایپ پس منظر میں کب گئی» کے مسئلے کو حل کرتا ہے — یہ SDK، لائبریریوں اور ماڈیولر ایپلیکیشنز کے لیے اہم ہے۔ Jetpack Compose میں، زندگی کا دور LifecycleEventObserver اور collectAsStateWithLifecycle کے ذریعے منظم کیا جاتا ہے، جو پس منظر کے موڈ میں خود بخود ڈیٹا اکٹھا کرنا معطل کر دیتا ہے۔ Android 14 (API 34) نے Service.onTimeout کے ذریعے پیش منظر سروس کے زندگی کے دور کی اطلاع شامل کی — سروس کو 6 گھنٹے میں مکمل ہونا چاہیے، ورنہ سسٹم اسے زبردستی روک دیتا ہے۔
| iOS | Android | تفصیل |
|---|---|---|
| Not Running | — | ایپ لانچ نہیں ہوئی |
| didFinishLaunching | Application.onCreate | لانچ پر پہلی ابتداء |
| Active | onResume | ایپ دکھائی دے رہی ہے اور ان پٹ قبول کر رہی ہے |
| Inactive | onPause | عارضی فوکس کا نقصان (کال، نوٹیفکیشن شیڈ) |
| Background | onStop | ایپ چھپی ہوئی، کوڈ چل سکتا ہے |
| Suspended | — | کوڈ نہیں چل رہا، میموری محفوظ ہے |
| Will Terminate | onDestroy | ایپ ختم ہو رہی ہے |
بنیادی فرق: iOS پس منظر میں داخل ہونے کے 5-10 سیکنڈ بعد ایپ کو زبردستی Suspended (کوڈ چلنا بند) میں منتقل کرتا ہے۔ Android طویل مدت کے لیے پس منظر کے کام (خدمات، WorkManager) کی اجازت دیتا ہے، لیکن Doze Mode (Android 6+) اور پس منظر کی پابندیوں (Android 12+) کی حدود کے ساتھ۔ Android میں ProcessLifecycleOwner iOS میں UIApplicationDidEnterBackgroundNotification کے برابر ہے، اس فرق کے ساتھ کہ یہ فوکس کھونے کے بعد نہیں بلکہ پس منظر میں کسی بھی منتقلی پر چلتا ہے۔
تمام زندگی کے دور کی ریاستوں کو سنبھالتے ہوئے ایک بنیادی AppDelegate نفاذ۔ پس منظر میں جاتے وقت ڈیٹا محفوظ کرنا اور واپس آتے وقت یوزر انٹرفیس اپ ڈیٹ کرنا۔
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
Analytics.shared.initialize()
return true
}
func applicationDidBecomeActive(_ application: UIApplication) {
NotificationCenter.default.post(name: .appDidBecomeActive, object: nil)
}
func applicationWillResignActive(_ application: UIApplication) {
NotificationCenter.default.post(name: .appWillResignActive, object: nil)
}
func applicationDidEnterBackground(_ application: UIApplication) {
CoreDataManager.shared.saveContext()
UserDefaults.standard.synchronize()
}
func applicationWillEnterForeground(_ application: UIApplication) {
NetworkManager.shared.refreshSession()
}
}
AppDelegate زندگی کے دور کا مرکزی نقطہ ہے۔ applicationDidEnterBackground ایک اہم طریقہ ہے: iOS محفوظ کرنے کے لیے ~5 سیکنڈ دیتا ہے۔ applicationDidBecomeActive — یوزر انٹرفیس اپ ڈیٹ کریں، اینیمیشن دوبارہ شروع کریں۔ SceneDelegate (iOS 13+) کے لیے، زندگی کے دور کی منطق مناظر میں تقسیم کی جاتی ہے: sceneDidBecomeActive / sceneDidEnterBackground انفرادی ونڈوز کا انتظام کرتے ہیں۔
کھڑکیوں والی iPad ایپلیکیشنز کے لیے SceneDelegate۔ ہر منظر کا اپنا زندگی کا دور ہوتا ہے، دوسری ونڈوز سے آزاد۔
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(
_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions
) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.rootViewController = ViewController()
window?.makeKeyAndVisible()
}
func sceneDidBecomeActive(_ scene: UIScene) {
PlayerManager.shared.resume()
}
func sceneDidEnterBackground(_ scene: UIScene) {
PlayerManager.shared.pause()
CoreDataManager.shared.saveContext()
}
func sceneDidDisconnect(_ scene: UIScene) {
PlayerManager.shared.cleanup()
}
}
SceneDelegate ایک انفرادی منظر کے زندگی کے دور کا انتظام کرتا ہے۔ sceneDidBecomeActive / sceneDidEnterBackground ایک مخصوص ونڈو کے لیے AppDelegate طریقوں کے برابر ہیں۔ sceneDidDisconnect منظر بند ہونے پر کال کیا جاتا ہے (صارف نے iPad پر ونڈو بند کی)۔ iOS 12 اور نیچے کے ساتھ مطابقت کے لیے، AppDelegate کو SceneDelegate منطق کو نقل کرنا چاہیے۔ iOS 17+ میں، آپ scenePhase کی بنیاد پر کاموں کو خود بخود روکنے/دوبارہ شروع کرنے کے لیے @Observable استعمال کر سکتے ہیں۔
ProcessLifecycleOwner ٹریک کرتا ہے کہ ایپ عمل کی سطح پر پیش منظر/پس منظر میں کب ہے۔ یہ عالمی زندگی کے دور کے انتظام کے لیے بہترین طریقہ ہے۔
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 ایپ کی سطح پر پس منظر میں منتقلی کو ٹریک کرنے کا واحد صحیح طریقہ ہے۔ ON_START اس وقت چلتا ہے جب ایپ دکھائی دیتی ہے (پیش منظر)، ON_STOP — جب مکمل طور پر چھپی ہوتی ہے (پس منظر)۔ Activity کے زندگی کے دور کے برعکس، ProcessLifecycleOwner کسی مخصوص اسکرین سے منسلک نہیں ہے۔ Jetpack Compose کے لیے، دستی مشاہدے کے بجائے LifecycleResumeEffect یا collectAsStateWithLifecycle استعمال کریں۔
ViewModel + Lifecycle زندگی کے دور کے انتظام کے لیے صحیح Android آرکیٹیکچر ہے۔ ViewModel خود بخود onDestroy پر صاف ہو جاتا ہے، لیک کو روکتا ہے۔
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 — وسائل آزاد کیے جا رہے ہیں")
}
}
// 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 — اینیمیشن روکے جا رہے ہیں")
}
override fun onDestroy() {
super.onDestroy()
Logger.d("Activity destroyed — صفائی")
}
}
ViewModel اسکرین گھومنے سے بچ جاتا ہے اور صرف Activity ختم ہونے پر تباہ ہوتا ہے۔ onCleared() وسائل کو آزاد کرنے اور سٹریمز سے سبسکرپشن ہٹانے کی جگہ ہے۔ LiveData خود بخود onPause پر مشاہدہ روک دیتا ہے اور onResume پر دوبارہ شروع کر دیتا ہے — یہ پس منظر کے کام کے دوران لیک اور کریشوں سے تحفظ فراہم کرتا ہے۔ Compose میں، اسی مقصد کے لیے collectAsStateWithLifecycle() استعمال کریں۔
اکثر پوچھے گئے سوالات
چھوٹا کرنے پر، ایپ فعال سے غیر فعال (مختصراً)، پھر پس منظر میں چلی جاتی ہے۔ چند سیکنڈ کے بعد، سسٹم اسے suspended میں منتقل کر سکتا ہے — کوڈ نہیں چلتا، میموری محفوظ ہے۔ جب میموری کم ہوتی ہے، سسٹم معطل ایپ کو ختم کر دیتا ہے (willTerminate کال نہیں کیا جاتا)۔ اپنا ڈیٹا applicationDidEnterBackground میں محفوظ کریں — یہ محفوظ کرنے کا آخری ضمانت شدہ نقطہ ہے۔
کم از کم لازمی: applicationDidEnterBackground — صارف کا ڈیٹا محفوظ کریں؛ applicationWillEnterForeground — یوزر انٹرفیس اپ ڈیٹ کریں؛ Android میں onPause — اینیمیشن/سینسر روکیں۔ ProcessLifecycleOwner ہینڈلنگ کو آسان بناتا ہے: onResume — onPause پیش منظر کے لیے، onStart — onStop مرئیت کے لیے۔ ضرورت کے مطابق دیگر ریاستوں کو سنبھالیں — تمام ریاستیں ہر ایپلیکیشن کے لیے اہم نہیں ہیں۔
AppDelegate پوری ایپلیکیشن کا عالمی مندوب ہے (لانچ، پس منظر میں منتقلی)۔ SceneDelegate (iOS 13+) ایک انفرادی ونڈو (منظر) کے زندگی کے دور کا انتظام کرتا ہے — کھڑکیوں والی iPad ایپلیکیشنز میں، ہر منظر کا اپنا زندگی کا دور ہوتا ہے۔ iOS 12 اور نیچے کے لیے، تمام زندگی کا دور AppDelegate کے ذریعے سنبھالا جاتا ہے۔ iPadOS 16+ کے ساتھ، Stage Manager کے لیے SceneDelegate لازمی ہے۔
ProcessLifecycleOwner AndroidX Lifecycle کا ایک جزو ہے جو پوری ایپلیکیشن (عمل) کے زندگی کے دور کو ٹریک کرتا ہے، نہ کہ کسی انفرادی Activity کا۔ یہ دو اہم واقعات فراہم کرتا ہے: ON_RESUME (ایپ پیش منظر میں) اور ON_STOP (ایپ پس منظر میں)۔ یہ SDK، تجزیات، نیٹ ورک مانیٹرز کی ابتداء/صفائی کے لیے استعمال ہوتا ہے — ہر وہ چیز جسے موجودہ اسکرین سے قطع نظر، ایپ کے پس منظر میں جانے پر رد عمل ظاہر کرنا چاہیے۔
Jetpack Compose میں، LocalLifecycleOwner.current.lifecycle یا collectAsStateWithLifecycle() فنکشن کے ذریعے LifecycleEventObserver استعمال کریں۔ Compose اسکرینوں کے لیے، LifecycleResumeEffect استعمال کریں — DisposableEffect کی طرح، جو onResume پر چلتا ہے اور onPause پر صاف ہوتا ہے۔ lifecycleScope.launchWhenResumed — ایک کوروٹین جو پس منظر میں خود بخود معطل ہو جاتی ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔