onPause Android کے لائف سائیکل کا ایک طریقہ ہے جو اس وقت کال کیا جاتا ہے جب Activity ان پٹ فوکس کھو دیتا ہے لیکن اسکرین پر جزوی طور پر نظر آتا رہتا ہے۔ سسٹم onPause کو اس وقت کال کرتا ہے جب کوئی نیا Activity پیش منظر میں آتا ہے، ڈائیلاگ کھلتا ہے، حالیہ ایپس کا بٹن دبایا جاتا ہے، یا کوئی آنے والی کال آتی ہے۔ یہ طریقہ صارف کے ڈیٹا کو محفوظ کرنے کا آخری ضمانتی نقطہ ہے، کیونکہ onStop اور onDestroy کے بعد سسٹم اضافی کال کے بغیر عمل ختم کر سکتا ہے۔ onPause کے اندر، ڈویلپر ڈرافٹ محفوظ کرتا ہے، اینیمیشن روکتا ہے، کیمرہ جاری کرتا ہے اور SharedPreferences میں موجودہ UI حالت لکھتا ہے۔ مکمل Activity لائف سائیکل کے بارے میں مزید تفصیلات کے لیے مضمون پڑھیں Activity Lifecycle۔
اہم نکات
onPause Activity لائف سائیکل کا چوتھا طریقہ ہے، جو اس وقت کال کیا جاتا ہے جب اسکرین ان پٹ فوکس کھو دیتی ہے لیکن صارف کو جزوی طور پر نظر آتی رہتی ہے۔ یہ ایپ کے فعال طور پر چلنے اور چھپنے کے درمیان ایک «انتقالی» حالت ہے۔ سسٹم onPause کو درج ذیل منظرناموں میں کال کرتا ہے: دوسرا Activity کھلنا (نئی اسکرین موجودہ کو جزوی طور پر ڈھانپتی ہے)، ڈائیلاگ ونڈو ظاہر ہونا (Dialog، PopupWindow، Snackbar onPause کو متحرک نہیں کرتے، لیکن DialogFragment کرتا ہے)، حالیہ ایپس کا بٹن دبانا، آنے والی کال، اسکرین لاک کرنے کے لیے پاور بٹن دبانا۔
onPause کا بنیادی کام ایپ کو چھپائے جانے یا تباہ کیے جانے کے امکان کے لیے تیار کرنا ہے۔ یہ لائف سائیکل کا آخری نقطہ ہے جہاں ڈویلپر اس بات کا یقین کر سکتا ہے کہ سسٹم کے کسی دوسرے جزو میں منتقلی جاری رکھنے سے پہلے اس کا کوڈ عمل میں آئے گا۔ onPause کے بعد، سسٹم onStop کال کرتا ہے (اگر Activity مکمل طور پر چھپ جاتا ہے)، جس کے بعد عمل بغیر کسی اضافی اطلاع کے کسی بھی وقت ختم کیا جا سکتا ہے۔
Android Developers دستاویزات (2025) کے مطابق، onPause کو جتنا ممکن ہو ہلکا اور تیز ہونا چاہیے۔ جب تک onPause کنٹرول واپس نہیں کرتا، سسٹم اگلا Activity شروع نہیں کر سکتا — اس کا مطلب ہے کہ صارف اسکرین کی منتقلی میں تاخیر دیکھتا ہے۔ Google 100 ملی سیکنڈ سے کم میں onPause مکمل کرنے کی سفارش کرتا ہے، اور تمام طویل کارروائیاں (ڈیٹا بیس میں محفوظ کرنا، ڈسک پر لکھنا) coroutines یا apply() کے ذریعے غیر ہم وقت ساز طور پر کی جانی چاہئیں۔
Activity میں، onPause طریقہ ہر بار کال کیا جاتا ہے جب اسکرین فعال رہنا بند کر دیتی ہے لیکن جزوی طور پر دکھائی دیتی رہ سکتی ہے۔ ایک عام مثال: صارف نقشہ جات ایپ کھولتا ہے، مقام شیئر کریں پر ٹیپ کرتا ہے، اور نقشہ جات کے اوپر ایک سسٹم ایپ سلیکشن ڈائیلاگ ظاہر ہوتا ہے۔ نقشہ جات کا Activity onPause حاصل کرتا ہے لیکن ڈائیلاگ کے نیچے نظر آتا رہتا ہے۔ جب ڈائیلاگ بند ہوتا ہے، نقشہ جات onStart کال کیے بغیر onResume حاصل کرتا ہے (اسکرین مکمل طور پر چھپی نہیں تھی)۔
class NoteEditorActivity : AppCompatActivity() {
private var binding: ActivityNoteEditorBinding? = null
private val prefs by lazy {
getSharedPreferences("note_drafts", Context.MODE_PRIVATE)
}
override fun onPause() {
super.onPause()
// نوٹ کا ڈرافٹ محفوظ کریں — غیر ہم وقت ساز
prefs.edit()
.putString("draft_title", binding?.titleInput?.text.toString())
.putString("draft_body", binding?.bodyInput?.text.toString())
.putLong("draft_timestamp", System.currentTimeMillis())
.apply()
// ویڈیو روکیں
binding?.videoPlayer?.pause()
// خصوصی وسائل جاری کریں
releaseCamera()
releaseAudioFocus()
}
override fun onResume() {
super.onResume()
// ڈرافٹ بحال کریں
binding?.titleInput?.setText(prefs.getString("draft_title", ""))
binding?.bodyInput?.setText(prefs.getString("draft_body", ""))
acquireCamera()
acquireAudioFocus()
}
}
NoteEditorActivity کی مثال onPause کے صحیح طریقے سے نمٹنے کو ظاہر کرتی ہے: apply() کے ذریعے SharedPreferences میں ڈرافٹ محفوظ کرنا، ویڈیو فائل کو روکنا، کیمرہ اور آڈیو فوکس جاری کرنا۔ ہر کال ہلکی اور تیز ہے، ANR کو متحرک کرنے کے لیے کافی دیر تک UI تھریڈ کو روکے بغیر۔ ترتیب پر توجہ دیں: super.onPause() پہلی لائن میں کال کیا جاتا ہے — یہ اس بات کی ضمانت دیتا ہے کہ صارف کوڈ میں مستثنیٰ ہونے پر بھی سسٹم منطق عمل میں آئے گی۔
onPause آخری نقطہ ہے جہاں ڈویلپر ایپ کے چھپنے یا سسٹم کے ذریعے ختم ہونے سے پہلے صارف کے ڈیٹا کو قابل اعتماد طریقے سے محفوظ کر سکتا ہے۔ onStop کے بعد، سسٹم میموری کم ہونے پر onDestroy کال کیے بغیر عمل ختم کر سکتا ہے۔ onSaveInstanceState() طریقہ onPause کے بعد کال کیا جاتا ہے، لیکن اس کا Bundle طویل مدتی ذخیرہ کرنے کے لیے نہیں ہے — یہ صرف اگلے onCreate تک زندہ رہتا ہے۔
غیر ہم وقت ساز apply() کے ساتھ SharedPreferences onPause میں تھوڑی مقدار میں ڈیٹا محفوظ کرنے کا بہترین طریقہ ہے commit() کے برعکس، جو ڈیٹا کو ہم وقت ساز طور پر ڈسک پر لکھتا ہے اور بولین لوٹاتا ہے، apply() فوری طور پر ڈیٹا کو میموری میں محفوظ کرتا ہے اور ڈسک پر غیر ہم وقت ساز تحریر کا شیڈول بناتا ہے۔ یہ commit() کے 10–100 ملی سیکنڈ کے مقابلے UI تھریڈ پر 1 ملی سیکنڈ سے بھی کم لیتا ہے۔
override fun onPause() {
super.onPause()
// ❌ برا: ہم وقت ساز تحریر تھریڈ کو روکتی ہے
// prefs.edit().putInt("score", score).commit()
// ✅ اچھا: غیر ہم وقت ساز تحریر
prefs.edit().putInt("score", score).apply()
// پیچیدہ اشیاء کے لیے — ViewModel میں کیشنگ
viewModel.saveState()
}
onPause میں ساختہ ڈیٹا (Room کے ذریعے SQLite) کے لیے، lifecycleScope کے ساتھ coroutines استعمال کیے جاتے ہیں۔ ViewModelScope ViewModel کے تباہ ہونے پر خود بخود coroutine کو منسوخ کر دیتا ہے، جو بند ڈیٹا بیس میں لکھنے سے روکتا ہے۔ coroutines کے ساتھ Room کے ذریعے لکھنے میں 5–15 ملی سیکنڈ لگتے ہیں اور UI تھریڈ کو نہیں روکتا۔
// ViewModel میں:
fun saveDraft(title: String, body: String) {
viewModelScope.launch(Dispatchers.IO) {
noteDao.insert(NoteDraft(title = title, body = body))
}
}
// Activity.onPause میں:
viewModel.saveDraft(
binding?.titleInput?.text.toString(),
binding?.bodyInput?.text.toString()
)
Fragment میں onPause اس وقت کال کیا جاتا ہے جب Fragment فعال رہنا بند کر دیتا ہے لیکن نظر آتا رہ سکتا ہے۔ یہ اس وقت ہوتا ہے جب: FragmentTransaction کے ذریعے Fragment کو دوسرے Fragment سے تبدیل کیا جاتا ہے؛ Fragment ViewPager میں موجودہ صفحہ نہیں رہتا؛ Fragment پر مشتمل Activity onPause حاصل کرتا ہے۔ Activity onPause اور Fragment onPause کے درمیان تعامل سختی سے درجہ بندی کا حامل ہے: پہلے Activity onPause حاصل کرتا ہے، پھر اس کے تمام Fragments۔
class MapFragment : Fragment() {
private var mapController: MapController? = null
override fun onPause() {
super.onPause()
mapController?.stopFollowMode()
binding?.mapContainer?.alpha = 0.7f
}
override fun onResume() {
super.onResume()
binding?.mapContainer?.alpha = 1.0f
if (isVisible) {
mapController?.startFollowMode()
}
}
}
onPause میں نقشوں کے ساتھ کام کرنے کی خصوصیات: Google Maps اور Yandex Maps فعال فالو موڈ میں اہم GPU وسائل استعمال کرتے ہیں۔ فوکس کھونے پر، نقشہ اینیمیشن کو غیر فعال کرنا اور مارکر اپ ڈیٹ فریکوئنسی کم کرنا سمجھ میں آتا ہے، اور فوکس واپس آنے پر مکمل فعالیت بحال کرنی چاہیے۔ یہ اسکرینوں کے درمیان سوئچ کرتے وقت کارکردگی کو بہتر بناتا ہے اور بجلی کی کھپت کو کم کرتا ہے۔
نئے Android ڈویلپرز میں سب سے عام الجھنوں میں سے ایک onPause اور onStop کے درمیان فرق کو سمجھ نہ پانا ہے۔ آئیے ہر منظرنامے کا جائزہ لیں اور صحیح طریقہ کا تعین کریں۔
| منظرنامہ | onPause | onStop |
|---|---|---|
| ڈائیلاگ ونڈو کھولنا | کال ہوتا ہے | کال نہیں ہوتا |
| نیا Activity کھولنا (غیر شفاف) | کال ہوتا ہے | کال ہوتا ہے |
| ہوم بٹن دبانا | کال ہوتا ہے | کال ہوتا ہے |
| اسکرین لاک | کال ہوتا ہے | کال ہوتا ہے |
| آنے والی کال | کال ہوتا ہے | کال ہوتا ہے |
| شفاف Activity اوپر | کال ہوتا ہے | کال نہیں ہوتا |
| اسپلٹ اسکرین (آدھی اسکرین) | کال ہوتا ہے | کال نہیں ہوتا |
| PiP (پکچر-ان-پکچر) | کال ہوتا ہے | کال نہیں ہوتا |
بنیادی اصول: onPause فوکس کھونے پر کال ہوتا ہے، onStop صرف مکمل نمائش ختم ہونے پر کال ہوتا ہے۔ اگر Activity نظر آتا رہے (چاہے جزوی طور پر)، onStop کال نہیں ہوتا۔ یہ اسپلٹ اسکرین، PiP اور شفاف Activity موڈز کے لیے انتہائی اہم ہے — یہاں onPause/onResume کام کرتے ہیں، لیکن onStart/onStop نہیں کرتے۔
onPause وقت کے لحاظ سے سب سے اہم لائف سائیکل طریقہ ہے کیونکہ یہ اگلے Activity کی رینڈرنگ کو روکتا ہے۔ سسٹم نیا Activity دکھانے سے پہلے موجودہ Activity کے onPause کے مکمل ہونے کا انتظار کرتا ہے۔ اگر onPause 100 ملی سیکنڈ سے زیادہ لیتا ہے، تو صارف کو منتقلی میں تاخیر محسوس ہوتی ہے؛ اگر 5 سیکنڈ سے زیادہ لیتا ہے، تو سسٹم ANR دکھاتا ہے۔
Google Android Performance Guide (2025) onPause کے لیے درج ذیل سفارشات دیتا ہے: نیٹ ورک کی درخواستیں نہ کریں — انہیں منسوخ کر دیا جانا چاہیے یا WorkManager میں منتقل کر دیا جانا چاہیے؛ ڈسک پر بڑی فائلیں نہ لکھیں — پس منظر کے تھریڈ پر BufferedWriter استعمال کریں؛ پیچیدہ SQL سوالات نہ چلائیں — Room کارروائیاں coroutines کے ذریعے غیر ہم وقت ساز ہونی چاہئیں؛ نئی اشیاء بنانے سے گریز کریں — onPause میں کوڑا کرکٹ جمع کرنا تاخیر کو بڑھا دیتا ہے؛ SharedPreferences کے لیے commit() کے بجائے apply() استعمال کریں۔
override fun onPause() {
super.onPause()
// ❌ برا: HTTP درخواست UI کو روکتی ہے
// val response = api.syncSave(data).execute()
// ❌ برا: فائل میں ہم وقت ساز تحریر
// FileOutputStream(file).write(data)
// ✅ اچھا: غیر ہم وقت ساز محفوظ کرنا
lifecycleScope.launch {
withContext(Dispatchers.IO) {
api.saveData(data)
fileDao.write(data)
}
}
// ✅ اچھا: SharedPreferences میں ہلکی تحریر
prefs.edit().putString("key", value).apply()
}
Android Studio Profiler (CPU ٹریس) کے ذریعے onPause کی پروفائلنگ درست عملدرآمد کا وقت دکھاتی ہے۔ اگر onPause 100 ms سے زیادہ لیتا ہے، تو Profiler طریقہ کو پیلے رنگ میں نمایاں کرتا ہے، اور 500 ms سے زیادہ — سرخ رنگ میں۔ IT Sectr میں تجارتی منصوبوں میں، ہم Macrobenchmark ٹیسٹ استعمال کرتے ہیں جو خود بخود Activities کے درمیان منتقلی کے وقت کی جانچ کرتے ہیں اور CI پائپ لائن میں کارکردگی کی کمی کا اشارہ دیتے ہیں۔
تجربہ کار ڈویلپرز بھی onPause میں غلطیاں کرتے ہیں۔ آئیے پانچ عام مسائل اور ان کے حل کا جائزہ لیں۔
onPause میں ہم وقت ساز سوال (.executeAsObservable() coroutines کے بغیر) کے ساتھ Room DAO کال کرنا UI تھریڈ کو 10–50 ms کے لیے روکتا ہے۔ اگر اسی وقت GC یا تحریری مسابقت ہوتی ہے، تو تاخیر 200–500 ms تک پہنچ سکتی ہے۔ حل: Dispatchers.IO کے ساتھ coroutines یا SharedPreferences کے لیے apply() استعمال کریں۔
onPause سننے والوں کو رجسٹر کرنے کی جگہ نہیں ہے۔ اگر آپ onPause میں BroadcastReceiver رجسٹر کرتے ہیں، تو یہ اس وقت فعال رہے گا جب Activity نظر نہیں آ رہا۔ رجسٹریشن صرف onStart/onResume میں ہونی چاہیے، اور onPause/onStop میں — صرف رجسٹریشن منسوخ کرنا۔ استثناء Intent پر مبنی APIs ہیں جنہیں کال سے پہلے رجسٹریشن کی ضرورت ہوتی ہے۔
اگر onPause میں کوئی غیر ہینڈل مستثنیٰ ہوتا ہے، تو سسٹم onStop اور onDestroy کال نہیں کرتا۔ Activity ایک غیر متعین حالت میں پھنس جاتا ہے، اور واپسی پر onResume جاری کردہ وسائل کو صحیح طریقے سے بحال نہیں کر سکتا۔ حل: Log.e() کے ذریعے لاگنگ کے ساتھ اہم کارروائیوں کو try/catch میں لپیٹیں۔
onPause میں وہ ڈیٹا محفوظ کرنے کی ضرورت نہیں ہے جسے آسانی سے بحال کیا جا سکتا ہے۔ مثال کے طور پر، API درخواستوں کے نتائج onPause میں نہیں بلکہ حاصل کرنے کے وقت Room یا DataStore میں کیے جاتے ہیں۔ صرف وہی محفوظ کریں جو صارف نے دستی طور پر درج کیا اور خود بخود بحال نہیں کیا جا سکتا — فیلڈز میں متن، منتخب کردہ اشیاء، اسکرول پوزیشن۔
super.onPause() کال کیا جانا چاہیے، لیکن onCreate کے برعکس، اسے چھوڑنے سے فوری کریش نہیں ہوتا۔ سسٹم onPause میں super کی کمی کو «معاف» کر دیتا ہے، لیکن اندرونی سٹیٹ مشین غلط حالت میں چلی جاتی ہے۔ اگلی onResume کال ان پٹ فوکس بحال کرنے میں ناکام ہو سکتی ہے، جس سے Activity «منجمد» رہ جاتا ہے۔ ہمیشہ super.onPause() کو جتنی جلدی ممکن ہو کال کریں۔
اکثر پوچھے گئے سوالات
onPause میں finish() کال کرنے سے طریقہ سے واپس آنے کے فوراً بعد Activity ختم ہو جائے گا۔ یہ ایک درست منظرنامہ ہے اگر فوکس کھونے پر اسکرین بند کرنے کی ضرورت ہو (مثال کے طور پر، ایپ کو چھوٹا کرتے وقت توثیقی اسکرین)۔ تاہم، finish() مکمل ختم کرنے کا چکر شروع کرتا ہے: onStop onDestroy، جو منتقلی میں تاخیر کا اضافہ کرتا ہے۔ onPause میں finish() صرف اس وقت استعمال کریں جب واقعی ضروری ہو۔
onPause اس ڈیٹا کو محفوظ کرنے کے لیے ہے جسے عمل ختم ہونے کے بعد بھی زندہ رہنا چاہیے (SharedPreferences/Room میں ڈرافٹ)۔ onSaveInstanceState عارضی UI حالت محفوظ کرنے کے لیے ہے جو صرف اگلے onCreate تک ضروری ہے (اسکرول پوزیشن، منتخب ٹیب)۔ onSaveInstanceState کا Bundle ایپ کے مکمل ختم ہونے پر محفوظ نہیں رہتا — یہ صرف میموری میں موجود ہوتا ہے۔ onPause ڈیٹا ڈسک پر محفوظ ہوتا ہے اور ریبوٹ کے بعد بھی زندہ رہتا ہے۔
سفارش نہیں کی جاتی۔ onPause میں ڈائیلاگ یا پاپ اپ کھولنا WindowLeakException کا سبب بنتا ہے اگر Activity پہلے ہی ختم ہو چکا ہے۔ اگر فوکس کھونے پر اطلاع دکھانے کی ضرورت ہو تو NotificationManager (سسٹم اطلاعات) استعمال کریں — یہ محفوظ ہے اور صارف کی توقع کے مطابق ہے۔ التوا والے اقدامات کے لیے AlarmManager یا WorkManager استعمال کریں۔
onPause کے Activity کے فعال رہنا بند کرنے سے پہلے کال ہونے کی ضمانت ہے۔ اگر سسٹم میموری خالی کرنے کے لیے عمل ختم کرتا ہے تو onStop کال نہیں ہو سکتا — اس صورت میں، onDestroy بھی کال نہیں ہوتا۔ onPause onResume کے بعد واحد طریقہ ہے جو ہمیشہ کال ہوتا ہے، فوکس کھونے کی وجہ سے قطع نظر۔ لہذا، تمام اہم ڈیٹا بالکل onPause میں محفوظ کیا جاتا ہے۔
onPause کی جانچ کے لیے Robolectric یا AndroidX Test کے FragmentScenario کا استعمال کیا جاتا ہے۔ FragmentScenario.create() moveToState(State.STARTED) moveToState(State.RESUMED) moveToState(State.STARTED) ترتیب وار onPause کال کرتا ہے۔ پھر تصدیق کی جاتی ہے کہ ڈیٹا SharedPreferences میں محفوظ ہوا یا کیمرہ کسی جعلی آبجیکٹ کے ذریعے جاری کیا گیا۔ Robolectric 4.12+ فزیکل ڈیوائس کے بغیر onPause/onResume ایمولیشن کو سپورٹ کرتا ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں