onDestroy — Android میں Activity اور Fragment کے زندگی کے دورانیے کا آخری طریقہ، جو جزو کی مکمل تباہی سے پہلے کال کیا جاتا ہے۔ onDestroy اشارہ کرتا ہے کہ Activity یا Fragment اپنا کام ختم کر رہا ہے: تمام وسائل جاری کر دیے جائیں، نیسٹڈ فریگمنٹس تباہ کر دیے جائیں، ViewModel صاف کیا جائے۔ Google کے مطابق، onDestroy Activity کے خاتمے کے 100% معاملات میں کال کیا جاتا ہے، لیکن عمل کی موت (process death) کے دوران نظام onDestroy کال کو مکمل طور پر چھوڑ سکتا ہے۔ onDestroy پر Android دستاویزات زور دیتی ہیں کہ یہ طریقہ غیر معمولی خاتمے پر کال کی ضمانت نہیں دیتا۔
اہم نکات
onDestroy — ایک کال بیک طریقہ ہے جسے Android Activity یا Fragment کو مکمل طور پر تباہ کرنے سے پہلے کال کرتا ہے۔ یہ ڈیویلپر کے لیے وسائل جاری کرنے، پس منظر کے آپریشنز منسوخ کرنے اور ڈیٹا کے کام کو ختم کرنے کا آخری موقع ہے۔ onDestroy کے عمل درآمد کے بعد، Activity/Fragment مثال کو کوڑا کرکٹ جمع کرنے (GC) کے لیے نشان زد کیا جاتا ہے اور مزید استعمال نہیں کیا جا سکتا۔
onDestroy کال کرنے کی وجوہات:
Google Android Vitals کے اعدادوشمار (2025) کے مطابق، Activity کی تباہی کے تمام معاملات میں سے تقریباً 12% اسکرین گھماؤ کی وجہ سے، 65% finish() کی وجہ سے اور 23% ترتیب میں تبدیلیوں کی وجہ سے ہوتے ہیں۔ onDestroy چھوڑے جانے والی عمل کی موت کا فیصد کم RAM (4 GB سے کم) والے آلات کے لحاظ سے تقریباً 5–8% ہے۔
onDestroy زیادہ تر معیاری منظرناموں میں کال کیا جاتا ہے، لیکن اہم استثنات ہیں جنہیں ڈیویلپر کو مدنظر رکھنا چاہیے۔ onDestroy کال کی ضمانتوں کو سمجھنا ایپلیکیشن فن تعمیر کے لیے اہم ہے، خاص طور پر ڈیٹا کو محفوظ کرنے اور WorkManager کے کاموں کو منسوخ کرنے کے لیے۔
onDestroy کب کال کیا جاتا ہے:
onDestroy کب نہیں کال کیا جاتا:
onDestroy کال کی ضمانت کی کمی کی وجہ سے، Google تجویز کرتا ہے: اہم ڈیٹا محفوظ کرنے کے لیے کبھی بھی onDestroy پر انحصار نہ کریں۔ onSaveInstanceState()، WorkManager یا خودکار محفوظ کرنے والے Room کا استعمال کریں۔ onDestroy وسائل جاری کرنے کے لیے ہے، استقامت (persistence) کے لیے نہیں۔
onDestroy Activity اور Fragment دونوں کے لیے موجود ہے، لیکن مختلف معاہدوں کے ساتھ۔ Fragment کا زندگی کا دورانیہ زیادہ تفصیلی ہے: onDestroy کے علاوہ، onDestroyView (View کا درجہ بندی تباہ کرنا) اور onDetach (Activity سے علیحدگی) بھی ہیں۔
| جزو | تباہی کے طریقے | ترتیب | ViewModel بچتا ہے |
|---|---|---|---|
| Activity | onDestroy | onPause → onStop → onDestroy | نہیں (صرف اگر ViewModelStore محفوظ نہ کیا گیا ہو) |
| Fragment | onDestroyView, onDestroy, onDetach | onPause → onStop → onDestroyView → onDestroy → onDetach | ہاں، اگر Fragment نہ ہٹایا گیا ہو |
بنیادی فرق: Fragment کا View خود Fragment سے زیادہ بار دوبارہ بنایا جاتا ہے۔ اسکرین گھماؤ کے دوران، Fragment onDestroyView (View تباہی) سے گزرتا ہے، لیکن Fragment خود اور اس کا ViewModel زندہ رہتے ہیں۔ onDestroyView میموری لیک سے بچنے کے لیے View حوالہ جات صاف کرنے کی صحیح جگہ ہے۔ Fragment کا onDestroy Activity کے onDestroy جیسا ہے، جو Fragment کے مکمل طور پر ہٹائے جانے پر کال کیا جاتا ہے۔
چائلڈ فریگمنٹس پیرنٹ Fragment کے onDestroy سے پہلے تباہ ہو جاتے ہیں۔ Activity میں، چائلڈ فریگمنٹس کو onDestroy اس وقت ملتا ہے جب پیرنٹ Activity کا onDestroy کال کیا جاتا ہے۔ ترتیب ضمانت شدہ ہے: فریگمنٹس ان پر مشتمل Activity سے پہلے ختم ہوتے ہیں۔
onDestroy ان تمام وسائل کو جاری کرنے کے لیے ہے جو Activity یا Fragment سے زیادہ زندہ نہیں رہنے چاہئیں۔ onStop کے برعکس، جو واپسی تک وسائل جاری کرتا ہے، onDestroy حتمی صفائی کرتا ہے۔
onDestroy میں لازمی اقدامات کی جانچ کی فہرست:
onDestroy میں کیا نہ کریں: onDestroy میں ڈیٹا محفوظ نہ کریں — onPause یا onSaveInstanceState استعمال کریں۔ نیا Service یا WorkManager کام شروع نہ کریں — Activity تباہ ہو جائے گی اور آپ نتیجہ ٹریک نہیں کر سکیں گے۔ یوزر انٹرفیس کو اپ ڈیٹ کرنے کی کوشش نہ کریں — View کا درجہ بندی پہلے ہی تباہ ہو چکا ہے یا تباہی کے عمل میں ہے؛ findViewById() کال کرنے پر null واپس آئے گا۔
ViewModel اسکرین گھماؤ کے دوران Activity کے onDestroy سے بچنے کے لیے ڈیزائن کیا گیا ہے، لیکن finish() کے دوران Activity کے ساتھ تباہ ہو جاتا ہے۔ یہ غیر متناسب رویہ ڈیویلپرز کے درمیان الجھن کی بنیادی وجہ ہے۔
اسکرین گھماؤ کے دوران:
finish() کے دوران (صارف نے «واپس» دبایا):
لہذا، onDestroy میں viewModelScope منسوخ کرنا ضروری نہیں ہے — ViewModel خود یہ کرے گا۔ اگر آپ lifecycleScope (ViewModel سے نہیں، Activity سے منسلک) استعمال کر رہے ہیں، تو اسے onDestroy میں lifecycleScope.cancel() کے ذریعے منسوخ کریں یا Job کو دستی طور پر منظم کریں۔
Activity میں درست lifecycleScope انتظام کو ظاہر کرتا ہے: نیٹ ورک کی حیثیت کی نگرانی کے لیے ایک coroutine شروع کی جاتی ہے اور onDestroy میں منسوخ کی جاتی ہے۔
class NetworkMonitorActivity : AppCompatActivity() {
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
Log.d("NetworkMonitor", "نیٹ ورک دستیاب")
}
override fun onLost(network: Network) {
Log.d("NetworkMonitor", "نیٹ ورک ختم ہو گیا")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_network)
val connectivityManager = getSystemService(ConnectivityManager::class.java)
connectivityManager.registerDefaultNetworkCallback(networkCallback)
lifecycleScope.launch {
Log.d("NetworkMonitor", "نیٹ ورک کی نگرانی شروع ہو گئی")
}
}
override fun onDestroy() {
super.onDestroy()
val connectivityManager = getSystemService(ConnectivityManager::class.java)
connectivityManager.unregisterNetworkCallback(networkCallback)
Log.d("NetworkMonitor", "onDestroy: کال بیک منسوخ کر دیا گیا")
}
}
onDestroy میں، نیٹ ورک کال بیک کی رجسٹریشن منسوخ کی جاتی ہے۔ lifecycleScope زندگی کے دورانیے کے تباہ ہونے پر خودکار طور پر منسوخ ہو جاتا ہے — علیحدہ coroutine منسوخی کی ضرورت نہیں ہے۔ نیٹ ورک کال بیک کو ضرور منسوخ کرنا چاہیے، ورنہ یہ Activity تباہ ہونے کے بعد بھی نظام میں رہے گا۔
ایک Fragment onDestroyView میں View حوالہ جات کو صحیح طریقے سے صاف کرتا ہے، بندشوں (closures) کی وجہ سے میموری لیک کو روکتا ہے۔
class ProfileFragment : Fragment() {
private var avatarView: ImageView? = null
private var progressBar: ProgressBar? = null
private val imageLoader = ImageLoader()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
avatarView = view.findViewById(R.id.avatar)
progressBar = view.findViewById(R.id.progress)
loadProfile()
}
private fun loadProfile() {
viewLifecycleOwner.lifecycleScope.launch {
try {
progressBar?.visibility = View.VISIBLE
val bitmap = imageLoader.load("https://example.com/avatar.png")
avatarView?.setImageBitmap(bitmap)
} finally {
progressBar?.visibility = View.GONE
}
}
}
override fun onDestroyView() {
super.onDestroyView()
avatarView = null
progressBar = null
imageLoader.cancel()
}
override fun onDestroy() {
super.onDestroy()
Log.d("ProfileFragment", "onDestroy: Fragment مکمل طور پر تباہ ہو گیا")
}
}
onDestroyView میں، View حوالہ جات null پر سیٹ کیے جاتے ہیں — یہ میموری لیک کو روکتا ہے اگر imageLoader میں بندش avatarView کا حوالہ رکھتی ہے۔ Fragment خود اور اس کا ViewModel onDestroy تک زندہ رہتے ہیں۔ imageLoader.cancel() لوڈنگ منسوخ کر دیتا ہے اگر Fragment اسکرین چھوڑ دیتا ہے۔
isFinishing() کا استعمال یہ فرق کرنے کی اجازت دیتا ہے کہ Activity صارف کے حکم سے ختم ہو رہی ہے یا دوبارہ تخلیق کے لیے۔
class AnalyticsActivity : AppCompatActivity() {
private val analytics = Analytics()
override fun onDestroy() {
if (isFinishing) {
Log.d("AnalyticsActivity", "Activity finish() کے ساتھ ختم ہو رہی ہے — تجزیہ بھیجا جا رہا ہے")
analytics.sendSessionEnd()
} else {
Log.d("AnalyticsActivity", "Activity دوبارہ بنائی جا رہی ہے (گھماؤ/ترتیب) — تجزیہ نہیں بھیجا جا رہا")
}
super.onDestroy()
}
}
isFinishing() کی جانچ تجزیہ، لاگنگ اور سیشن ڈیٹا کی صفائی کے لیے ایک اہم نمونہ ہے۔ گھماؤ کے دوران، سیشن ختم ہونے کے واقعات نہیں بھیجے جانے چاہئیں — صارف ابھی بھی ایپلیکیشن کے ساتھ کام کر رہا ہے۔ Google Analytics کے مطابق، غلط isFinishing() جانچ 40% جھوٹے سیشن واقعات کی وجہ ہے۔
اکثر پوچھے جانے والے سوالات
ہاں، ہو سکتا ہے — نظام کی طرف سے عمل کی موت، صارف کی طرف سے جبری روک یا غیر معمولی خاتمے کے دوران۔ Google کے مطابق، تقریباً 5–8% Activity ختم ہونے کے واقعات onDestroy کال کیے بغیر ہوتے ہیں۔ ڈیویلپرز کو اہم ڈیٹا محفوظ کرنے کے لیے onDestroy پر انحصار نہیں کرنا چاہیے — onPause یا onSaveInstanceState استعمال کریں۔
finish() — ایک کال جو Activity کی تباہی شروع کرتی ہے۔ onDestroy — ایک کال بیک جو finish() کے عمل درآمد کے دوران کال کیا جاتا ہے۔ عام خاتمے پر onDestroy کال ہونے کے لیے finish() ضروری ہے۔ finish() نظام یا ڈیویلپر کے ذریعے کال کیا جا سکتا ہے، onDestroy صرف ایک نظام کال بیک ہے۔
ہاں، یقیناً Activity اور Fragment دونوں میں۔ super.onDestroy() ChildFragmentManager، LoaderManager اور دیگر نظامی اجزاء کی مناسب صفائی کو یقینی بناتا ہے۔ super.onDestroy() چھوڑنے سے میموری لیک اور فریگمنٹ کی بحالی میں خرابیاں پیدا ہوتی ہیں۔
onCleared() Activity یا Fragment کے onDestroy کے بعد کال کیا جاتا ہے، جب ViewModel کی مزید ضرورت نہیں رہتی۔ اسکرین گھماؤ کے دوران، onCleared() کال نہیں کیا جاتا — ViewModel onDestroy سے بچ جاتا ہے۔ ترتیب: Activity/Fragment کا onDestroy → (ViewModelStore صاف ہوتا ہے) → onCleared()۔
تکنیکی طور پر ہاں، لیکن سفارش نہیں کی جاتی۔ Activity onDestroy کے فوراً بعد تباہ ہو جاتی ہے، اور شروع کردہ Service بے قابو رہ جاتا ہے۔ پس منظر کے کاموں کے لیے، تاخیر کے ساتھ WorkManager استعمال کریں: WorkManager Activity ختم ہونے کے بعد بھی عمل درآمد کی ضمانت دیتا ہے اور عمل کی موت سے بچ جاتا ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں