onResume — متد چرخه حیات Android است که زمانی فراخوانی میشود که Activity یا Fragment به پیشزمینه میآید و فوکوس ورودی دریافت میکند. در این حالت صفحه برای تعامل با کاربر آماده است: تمام رویدادهای لمسی، فشار کلیدها و حرکات به این مؤلفه هدایت میشوند. onResume حالت کاری Activity است که برنامه بیشتر وقت خود را در آن میگذراند. دقیقاً در اینجا دوربین باز میشود، پخش ویدیو شروع میشود، تشخیص گفتار آغاز میگردد و شنوندههای حسی که نیاز به دسترسی انحصاری دارند ثبت میشوند. درباره چرخه حیات کامل Activity در مقاله Activity Lifecycle بیشتر بخوانید.
نکات اصلی
onResume — سومین متد چرخه حیات Activity است که پس از onStart فراخوانی میشود و آمادگی صفحه برای تعامل کامل با کاربر را نشان میدهد. در این لحظه Activity در بالای پشته وظایف (back stack) قرار دارد، سیستم تمام رویدادهای ورودی را به آن هدایت میکند و برنامه میتواند هر عملیاتی را که نیاز به مشارکت فعال کاربر دارد آغاز کند: تماسهای ویدیویی، بازیها، ضبط صدا، نقاشی روی Canvas.
onResume بخشی از «عمر در پیشزمینه» (foreground lifetime) است — فاصله بین onResume و onPause. این فعالترین دوره کاری Activity است که برنامه حداکثر منابع را مصرف میکند: پردازنده برای پردازش لمسها، GPU برای رندر انیمیشنها، دوربین و میکروفون برای ضبط ویدیو. درک این سطح از چرخه حیات برای بهینهسازی مصرف انرژی حیاتی است — منابعی که در onResume باز میشوند باید بلافاصله در onPause بسته شوند.
طبق دادههای Google I/O 2025، میانگین زمانی که Activity در یک جلسه در حالت onResume میگذراند، ۲–۵ دقیقه برای برنامههای خبری و ۱۵–۳۰ دقیقه برای بازیها و پیامرسانها است. بقیه زمان Activity در حالتهای onPause، onStop یا onDestroy قرار دارد. این بدان معناست که بهینهسازی دقیقاً کد onResume بیشترین سود را در عملکرد و عمر باتری میدهد.
در Activity متد onResume هر بار که صفحه فوکوس ورودی دریافت میکند فراخوانی میشود — در اولین راهاندازی، هنگام بازگشت از Activity دیگر، هنگام بسته شدن پنجره دیالوگ، هنگام باز کردن قفل دستگاه. این یک متد داغ است که ممکن است چندین بار در طول یک جلسه فراخوانی شود و پیادهسازی آن باید تا حد امکان سبک باشد.
class CameraActivity : AppCompatActivity() {
private var cameraProvider: ProcessCameraProvider? = null
private var preview: Preview? = null
override fun onResume() {
super.onResume()
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener({
cameraProvider = cameraProviderFuture.get()
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
preview = Preview.Builder().build().also {
it.setSurfaceProvider(binding?.viewFinder?.surfaceProvider)
}
try {
cameraProvider?.unbindAll()
cameraProvider?.bindToLifecycle(
this, cameraSelector, preview
)
} catch (e: Exception) {
Log.e("Camera", "اتصال دوربین انجام نشد", e)
}
}, ContextCompact.getMainExecutor(this))
}
override fun onPause() {
super.onPause()
cameraProvider?.unbindAll()
preview = null
}
}
مثال با CameraX استفاده کلاسیک از onResume/onPause را نشان میدهد: دوربین یک منبع انحصاری است که فقط میتواند توسط یک برنامه در یک زمان استفاده شود. اتصال دوربین به چرخه حیات از طریق bindToLifecycle به طور خودکار دوربین را در onPause میبندد، اما فراخوانی صریح unbindAll آزادسازی فوری را تضمین میکند. این به ویژه هنگام جابجایی بین Activityها مهم است: دوربین باید قبل از اینکه Activity دیگری سعی در باز کردن آن کند آزاد شود.
onResume در Fragment پس از آنکه Activity حاوی آن onResume دریافت کرد فراخوانی میشود. با این حال به دلیل ویژگیهای FragmentManager و ViewPager، لحظه فراخوانی onResume برای Fragment میتواند نسبت به Activity به تأخیر بیفتد. به عنوان مثال، Fragment در ViewPager با offscreenPageLimit = 1 تنها زمانی که صفحه جاری شود onResume دریافت میکند، نه هنگام شروع Activity.
class VideoPlayerFragment : Fragment() {
private var exoPlayer: ExoPlayer? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
exoPlayer = ExoPlayer.Builder(requireContext()).build()
binding?.playerView?.player = exoPlayer
}
override fun onResume() {
super.onResume()
exoPlayer?.play()
if (userVisibleHint) {
startBiometricAuth()
}
}
override fun onPause() {
exoPlayer?.pause()
stopBiometricAuth()
super.onPause()
}
}
بررسی userVisibleHint در Fragment.onResume برای ViewPager ضروری است: Fragment ممکن است onResume دریافت کند اما توسط صفحه مجاور پنهان شده باشد (مثلاً در انتقال انیمیشنی). در چنین مواردی راهاندازی ویدیو یا بیومتریک در onResume بدون بررسی رویتپذیری منجر به رفتار غیرمنتظره میشود. از Fragment 1.5.0 به بعد، توصیه میشود از FragmentTransaction.setMaxLifecycle() برای کنترل دقیق چرخه حیات fragmentها در ViewPager2 استفاده کنید.
توسعهدهندگان اغلب onStart و onResume را اشتباه میگیرند و کد را در متد نامناسب قرار میدهند. قانون اصلی: onStart — برای منابعی که در رویتپذیری کار میکنند; onResume — برای منابعی که نیاز به فوکوس ورودی دارند. بیایید سناریوهای خاص و انتخاب صحیح متد را بررسی کنیم.
| عملیات | متد | دلیل |
|---|---|---|
| اشتراک موقعیت جغرافیایی | onStart / onStop | GPS میتواند با رویتپذیری جزئی کار کند |
| باز کردن دوربین | onResume / onPause | دوربین — منبع انحصاری |
| BroadcastReceiver | onStart / onStop | رویدادهای سیستمی نیاز به فوکوس ندارند |
| پخش ویدیو | onResume / onPause | ویدیو باید برای کاربر قابل مشاهده باشد |
| اسکن Bluetooth | onStart / onStop | اسکن میتواند در پسزمینه ادامه یابد |
| ضبط صدا (MediaRecorder) | onResume / onPause | ضبط نیاز به UI فعال دارد |
| شنوندههای حسی | onResume / onPause | حسگرها برای بازیها و حرکات |
| بهروزرسانی دادهها | onStart | دادههای تازه هنگام ظاهر شدن نیاز است |
قاعده عملی: اگر عملیات باید با ظاهر شدن پنجره دیالوگ قطع شود — از onResume/onPause استفاده کنید. اگر عملیات میتواند با پوشش جزئی صفحه ادامه یابد — از onStart/onStop استفاده کنید. به عنوان مثال، پخشکننده ویدیو باید هنگام باز شدن دیالوگ ویدیو را متوقف کند (onPause)، در حالی که موقعیت جغرافیایی میتواند به بهروزرسانی ادامه دهد (در onStart باقی میماند).
منابع انحصاری — اجزای دستگاهی هستند که فقط میتوانند توسط یک برنامه در یک لحظه خاص استفاده شوند. دوربین، میکروفون، خروجی ویدیو (MediaProjection)، آداپتور NFC در حالت خواندن، دستگاههای USB در حالت accessory — همه این منابع باید در onResume باز و در onPause آزاد شوند.
MediaRecorder برای ضبط صدا و ویدیو استفاده میشود. درخواست مجوزها و آمادهسازی MediaRecorder در onCreate انجام میشود و شروع ضبط در onResume. اگر کاربر به برنامه دیگری سوئیچ کند، onPause ضبط را متوقف میکند و onResume آن را از سر میگیرد. این رفتار استاندارد برای ضبطکنندههای صدا و برنامههای ضبط ویدیو است.
private var mediaRecorder: MediaRecorder? = null
private var isRecording = false
override fun onResume() {
super.onResume()
if (isRecording) {
mediaRecorder?.resume()
}
}
override fun onPause() {
if (isRecording) {
mediaRecorder?.pause()
}
super.onPause()
}
احراز هویت بیومتریک (BiometricPrompt) فقط زمانی باید فراخوانی شود که Activity در onResume است. اگر آن را در onCreate یا onStart فراخوانی کنید، دیالوگ بیومتریک ممکن است قبل از اتمام مقداردهی Activity ظاهر شود که منجر به پردازش نادرست نتیجه میشود. فراخوانی در onResume تضمین میکند که پنجره بیومتریک در زمینه صحیح نمایش داده شود.
سه الگوی تأیید شده کار با onResume را بررسی میکنیم که در پروژههای تجاری استفاده میشوند: بازنشانی تایمر عدم فعالیت، بهروزرسانی دادههای قابل مشاهده و یکپارچهسازی با Jetpack Navigation.
در برنامههای دارای دادههای محرمانه (بانکداری، کارتهای پزشکی) از onResume برای بازنشانی تایمر خروج خودکار استفاده میشود. اگر کاربر فعالانه با برنامه تعامل دارد، onResume در هر جابجایی بین صفحات فراخوانی میشود و تایمر بازنشانی میشود. اگر کاربر برنامه را کوچک کند، onPause تایمر را متوقف میکند و onResume هنگام بازگشت یا آن را بازنشانی میکند یا احراز هویت مجدد را درخواست میکند.
لیستی که باید در هر بازگشت به صفحه دادههای بهروز را نمایش دهد در onResume بهروزرسانی میشود. به عنوان مثال، اگر کاربر یک رکورد جدید در Activity دیگر ایجاد کرده و برگردد، onResume لیست را از پایگاه داده محلی یا از کش ViewModel بارگیری مجدد میکند. این امر سازگاری دادهها را بدون فراخوانی دستی notifyDataSetChanged تضمین میکند.
override fun onResume() {
super.onResume()
// ActivityResultLauncher نتیجه را برگرداند — لیست را بهروزرسانی میکنیم
viewModel.refreshList()
// بازنشانی تایمر عدم فعالیت
inactivityTimer.reset()
}
در Jetpack Navigation onResume فرگمنت در هر بازگشت به آن از طریق ناوبری برگشتی فراخوانی میشود. این ویژگی برای بازنشانی وضعیت UI استفاده میشود: مخفی کردن صفحهکلید، پاک کردن فیلدهای جستجو، بهروزرسانی عنوان نوار ابزار. OnBackPressedCallback در ترکیب با onResume کنترل کامل ناوبری را بدون تکرار کد فراهم میکند.
سؤالات متداول
onStart — صفحه قابل مشاهده است. onResume — صفحه فعال و آماده تعامل است. تصور کنید: تلویزیون تماشا میکنید (onStart)، اما کنترل را در دست میگیرید (onResume). تلویزیون همیشه قابل مشاهده است، اما تعامل فقط با کنترل شروع میشود. اگر کسی تلویزیون را با پرده بپوشاند — صفحه دیگر قابل مشاهده نیست (onStop). اگر کنترل را از شما بگیرند — تعامل متوقف میشود (onPause)، اما تلویزیون همچنان قابل مشاهده است.
onResume هر بار که Activity فوکوس ورودی دریافت میکند فراخوانی میشود. حداقل تعداد — یک بار (در هنگام راهاندازی). حداکثر به سناریوهای استفاده بستگی دارد: جابجایی بین صفحات، باز کردن دیالوگها، قفل و باز کردن سریع دستگاه — هر سناریو هنگام بازگشت به صفحه onResume را فراخوانی میکند.
دوربین — منبع انحصاری است که فقط برای یک برنامه در یک زمان قابل دسترسی است. اگر دوربین را در onCreate یا onStart باز کنید، حتی زمانی که برنامه شما غیرفعال است برای سایر برنامهها مسدود میماند. onResume تضمین میکند که دوربین فقط زمانی باز است که Activity در پیشزمینه است و onPause بلافاصله آن را میبندد. این استاندارد توسعه Android است که در مستندات CameraX و Camera2 API تثبیت شده است.
بله، اگر Activity بلافاصله پس از ظاهر شدن توسط Activity دیگری پوشانده شود، onResume رخ نمیدهد. به عنوان مثال، Activity A در متد onCreate یا onStart خود Activity B را راهاندازی میکند. در این حالت A onStart → onPause → onStop را دریافت میکند و onResume را رد میکند. سیستم onResume را فراخوانی نمیکند زیرا Activity A هرگز فوکوس ورودی دریافت نکرده است.
در onResume نمیتوان عملیات همزمان طولانی انجام داد: بارگیری دادههای بزرگ از شبکه، کوئریهای پیچیده SQL، پردازش تصاویر. متد onResume در رشته UI کار میکند و هر مسدودیتی بیش از ۱۰۰–۲۰۰ میلیثانیه منجر به تأخیر در پاسخگویی رابط میشود. همه عملیات سنگین باید ناهمزمان باشند — از طریق کوروتینها، RxJava یا WorkManager. همچنین توصیه نمیشود بدون بررسی در onResume finish() فراخوانی کنید — این میتواند به یک حلقه بینهایت بازآفرینی منجر شود.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.