Not Running — موبائل ایپلیکیشن کی لائف سائیکل کی ابتدائی حالت جب یہ ابھی تک لانچ نہیں ہوئی یا پہلے ہی کام ختم کر چکی ہے۔ جانیے کہ iOS اور Android اس حالت کا انتظام کیسے کرتے ہیں، کون سے واقعات Not Running سے منتقل کا سبب بنتے ہیں اور Swift اور Kotlin میں ایپلیکیشن کے آغاز اور اختتام کو صحیح طریقے سے کیسے سنبھالیں۔
اہم نکات
Not Running موبائل ایپلیکیشن کی بنیادی لائف سائیکل حالت ہے جس میں یہ آلے کی RAM میں لوڈ نہیں ہے اور سسٹم وسائل استعمال نہیں کرتی۔ iOS اور Android میں، اس حالت کا مطلب ایپلیکیشن سے وابستہ عملیوں اور دھاگوں کی مکمل غیر موجودگی ہے۔ صارف ہوم اسکرین پر ایپ کا آئیکن دیکھتا ہے، لیکن ایپلیکیشن خود فعال نہیں ہے اور حالیہ ایپس کی فہرست میں نہیں ہے۔
جب صارف ایپ آئیکن پر ٹیپ کرتا ہے، سسٹم ایک نیا عمل تخلیق کرتا ہے، قابل عمل کوڈ کو میموری میں لوڈ کرتا ہے اور تمام ضروری ڈیٹا ساختوں کو ابتدائیت دیتا ہے۔ اس عمل کو سرد آغاز (cold start) کہا جاتا ہے اور لوڈ وقت کے لحاظ سے یہ سب سے زیادہ وسائل طلب ہے۔
سسٹم ایپلیکیشن کو کسی بھی دوسری حالت سے Not Running میں لے جا سکتا ہے۔ اگر ایپلیکیشن بیک گراؤنڈ یا Suspended میں ہے، آپریٹنگ سسٹم کو حق ہے کہ اعلیٰ ترجیح کے کاموں کے لیے کافی RAM نہ ہونے پر اسے انلوڈ کرے — مثال کے طور پر، ایک فعال پیش منظر ایپلیکیشن کے لیے۔
ڈیویلپر کو غور کرنا چاہیے کہ ایپلیکیشن سسٹم کے ذریعے کسی بھی لمحے ختم کی جا سکتی ہے جب یہ بیک گراؤنڈ میں ہو۔ اس کا مطلب ہے کہ تمام غیر محفوظ ڈیٹا ضائع ہو سکتا ہے۔ لہذا، Active سے Background میں منتقل ہونے کے دوران کلیدی-قدر ذخیروں (UserDefaults, SharedPreferences) یا مقامی ڈیٹابیس میں حالت محفوظ کرنا انتہائی اہم ہے۔
iOS موجودہ ایپلیکیشن حالت کی بنیاد پر ترجیحات استعمال کرتا ہے: Active کی سب سے اعلیٰ ترجیح ہے، اس کے بعد Inactive، Background، Suspended، اور آخر میں Not Running — سب سے کم ترجیح۔ Android ایک مماثل عمل درجہ بندی استعمال کرتا ہے: پیش منظر عمل کی ترجیح 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 — سب سے آخر میں ختم ہوتی ہے |
سرد آغاز (cold start) اس وقت ہوتا ہے جب ایپلیکیشن Not Running سے براہ راست Active میں منتقل ہوتی ہے۔ سسٹم ایک نیا عمل بناتا ہے، کلاسز لوڈ کرتا ہے، جامع فیلڈز کو ابتدائیت دیتا ہے، مرکزی دھاگہ بناتا ہے اور UI فریم ورک شروع کرتا ہے۔ iOS پر، اس کا مطلب application(_:didFinishLaunchingWithOptions:) کو کال کرنا ہے، Android پر — Application.onCreate() اور Activity.onCreate() کو کال کرنا۔ سرد آغاز کا وقت ایپلیکیشن کی پیچیدگی پر منحصر 200 ms سے کئی سیکنڈ تک ہو سکتا ہے۔
گرم آغاز (warm start یا hot start) — ایپلیکیشن 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 بناتا ہے۔ اگر صارف واپس دبائے، 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 منٹ | ہاں — صحیح کام طے کرنا |
| آپریٹنگ سسٹم دوبارہ شروع | 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 سفارش کرتا ہے بہترین صارف تجربے کے لیے سرد آغاز 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 ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں