onResume — مبانی، تعامل با کاربر در Android

نویسنده: IT Sectr منتشر شده: 2026-03-04 زمان مطالعه: 10 دقیقه

onResume — متد چرخه حیات Android است که زمانی فراخوانی می‌شود که Activity یا Fragment به پیش‌زمینه می‌آید و فوکوس ورودی دریافت می‌کند. در این حالت صفحه برای تعامل با کاربر آماده است: تمام رویدادهای لمسی، فشار کلیدها و حرکات به این مؤلفه هدایت می‌شوند. onResume حالت کاری Activity است که برنامه بیشتر وقت خود را در آن می‌گذراند. دقیقاً در اینجا دوربین باز می‌شود، پخش ویدیو شروع می‌شود، تشخیص گفتار آغاز می‌گردد و شنونده‌های حسی که نیاز به دسترسی انحصاری دارند ثبت می‌شوند. درباره چرخه حیات کامل Activity در مقاله Activity Lifecycle بیشتر بخوانید.

نکات اصلی

  • onResume — Activity در پیش‌زمینه با فوکوس ورودی; پس از onStart یا پس از بازگشت از پنجره دیالوگ فراخوانی می‌شود
  • منابع انحصاری — دوربین، میکروفون، ضبط ویدیو در onResume باز و در onPause بسته می‌شوند
  • جفت onResume/onPause — منابعی که نیاز به فوکوس کامل دارند توسط این جفت مدیریت می‌شوند; در onResume ثبت و در onPause آزاد می‌شوند
  • onResume در مقابل onStart — onStart = رویت‌پذیری، onResume = تعامل; دیالوگ onResume را می‌پوشاند اما onStart را نه
  • زمان‌بندی — onResume باید سریع باشد; عملیات طولانی در اینجا پاسخگویی رابط را به تأخیر می‌اندازد
  • Fragment.onResume — پس از Activity.onResume فراخوانی می‌شود، زمانی که Fragment برای تعامل آماده است
  • onResume در Jetpack — lifecycleScope و LiveData از onResume برای مدیریت خودکار اشتراک‌ها استفاده می‌کنند

مبانی روش onResume در Android

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 بیشترین سود را در عملکرد و عمر باتری می‌دهد.

onResume در Activity

در Activity متد onResume هر بار که صفحه فوکوس ورودی دریافت می‌کند فراخوانی می‌شود — در اولین راه‌اندازی، هنگام بازگشت از Activity دیگر، هنگام بسته شدن پنجره دیالوگ، هنگام باز کردن قفل دستگاه. این یک متد داغ است که ممکن است چندین بار در طول یک جلسه فراخوانی شود و پیاده‌سازی آن باید تا حد امکان سبک باشد.

kotlin
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

onResume در Fragment پس از آن‌که Activity حاوی آن onResume دریافت کرد فراخوانی می‌شود. با این حال به دلیل ویژگی‌های FragmentManager و ViewPager، لحظه فراخوانی onResume برای Fragment می‌تواند نسبت به Activity به تأخیر بیفتد. به عنوان مثال، Fragment در ViewPager با offscreenPageLimit = 1 تنها زمانی که صفحه جاری شود onResume دریافت می‌کند، نه هنگام شروع Activity.

kotlin
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 استفاده کنید.

onResume در مقابل onStart: چه زمانی از کدام استفاده کنیم

توسعه‌دهندگان اغلب onStart و onResume را اشتباه می‌گیرند و کد را در متد نامناسب قرار می‌دهند. قانون اصلی: onStart — برای منابعی که در رویت‌پذیری کار می‌کنند; onResume — برای منابعی که نیاز به فوکوس ورودی دارند. بیایید سناریوهای خاص و انتخاب صحیح متد را بررسی کنیم.

عملیاتمتددلیل
اشتراک موقعیت جغرافیاییonStart / onStopGPS می‌تواند با رویت‌پذیری جزئی کار کند
باز کردن دوربینonResume / onPauseدوربین — منبع انحصاری
BroadcastReceiveronStart / onStopرویدادهای سیستمی نیاز به فوکوس ندارند
پخش ویدیوonResume / onPauseویدیو باید برای کاربر قابل مشاهده باشد
اسکن BluetoothonStart / onStopاسکن می‌تواند در پس‌زمینه ادامه یابد
ضبط صدا (MediaRecorder)onResume / onPauseضبط نیاز به UI فعال دارد
شنونده‌های حسیonResume / onPauseحسگرها برای بازی‌ها و حرکات
به‌روزرسانی داده‌هاonStartداده‌های تازه هنگام ظاهر شدن نیاز است

قاعده عملی: اگر عملیات باید با ظاهر شدن پنجره دیالوگ قطع شود — از onResume/onPause استفاده کنید. اگر عملیات می‌تواند با پوشش جزئی صفحه ادامه یابد — از onStart/onStop استفاده کنید. به عنوان مثال، پخش‌کننده ویدیو باید هنگام باز شدن دیالوگ ویدیو را متوقف کند (onPause)، در حالی که موقعیت جغرافیایی می‌تواند به به‌روزرسانی ادامه دهد (در onStart باقی می‌ماند).

مدیریت منابع انحصاری

منابع انحصاری — اجزای دستگاهی هستند که فقط می‌توانند توسط یک برنامه در یک لحظه خاص استفاده شوند. دوربین، میکروفون، خروجی ویدیو (MediaProjection)، آداپتور NFC در حالت خواندن، دستگاه‌های USB در حالت accessory — همه این منابع باید در onResume باز و در onPause آزاد شوند.

کار با MediaRecorder

MediaRecorder برای ضبط صدا و ویدیو استفاده می‌شود. درخواست مجوزها و آماده‌سازی MediaRecorder در onCreate انجام می‌شود و شروع ضبط در onResume. اگر کاربر به برنامه دیگری سوئیچ کند، onPause ضبط را متوقف می‌کند و onResume آن را از سر می‌گیرد. این رفتار استاندارد برای ضبط‌کننده‌های صدا و برنامه‌های ضبط ویدیو است.

kotlin
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 و onResume

احراز هویت بیومتریک (BiometricPrompt) فقط زمانی باید فراخوانی شود که Activity در onResume است. اگر آن را در onCreate یا onStart فراخوانی کنید، دیالوگ بیومتریک ممکن است قبل از اتمام مقداردهی Activity ظاهر شود که منجر به پردازش نادرست نتیجه می‌شود. فراخوانی در onResume تضمین می‌کند که پنجره بیومتریک در زمینه صحیح نمایش داده شود.

الگوها و توصیه‌ها

سه الگوی تأیید شده کار با onResume را بررسی می‌کنیم که در پروژه‌های تجاری استفاده می‌شوند: بازنشانی تایمر عدم فعالیت، به‌روزرسانی داده‌های قابل مشاهده و یکپارچه‌سازی با Jetpack Navigation.

بازنشانی تایمر عدم فعالیت

در برنامه‌های دارای داده‌های محرمانه (بانکداری، کارت‌های پزشکی) از onResume برای بازنشانی تایمر خروج خودکار استفاده می‌شود. اگر کاربر فعالانه با برنامه تعامل دارد، onResume در هر جابجایی بین صفحات فراخوانی می‌شود و تایمر بازنشانی می‌شود. اگر کاربر برنامه را کوچک کند، onPause تایمر را متوقف می‌کند و onResume هنگام بازگشت یا آن را بازنشانی می‌کند یا احراز هویت مجدد را درخواست می‌کند.

به‌روزرسانی داده‌ها هنگام بازگشت

لیستی که باید در هر بازگشت به صفحه داده‌های به‌روز را نمایش دهد در onResume به‌روزرسانی می‌شود. به عنوان مثال، اگر کاربر یک رکورد جدید در Activity دیگر ایجاد کرده و برگردد، onResume لیست را از پایگاه داده محلی یا از کش ViewModel بارگیری مجدد می‌کند. این امر سازگاری داده‌ها را بدون فراخوانی دستی notifyDataSetChanged تضمین می‌کند.

kotlin
override fun onResume() {
    super.onResume()
    // ActivityResultLauncher نتیجه را برگرداند — لیست را به‌روزرسانی می‌کنیم
    viewModel.refreshList()
    // بازنشانی تایمر عدم فعالیت
    inactivityTimer.reset()
}

Jetpack Navigation و onResume

در Jetpack Navigation onResume فرگمنت در هر بازگشت به آن از طریق ناوبری برگشتی فراخوانی می‌شود. این ویژگی برای بازنشانی وضعیت UI استفاده می‌شود: مخفی کردن صفحه‌کلید، پاک کردن فیلدهای جستجو، به‌روزرسانی عنوان نوار ابزار. OnBackPressedCallback در ترکیب با onResume کنترل کامل ناوبری را بدون تکرار کد فراهم می‌کند.

سؤالات متداول

تفاوت بین onResume و onStart به زبان ساده چیست؟

onStart — صفحه قابل مشاهده است. onResume — صفحه فعال و آماده تعامل است. تصور کنید: تلویزیون تماشا می‌کنید (onStart)، اما کنترل را در دست می‌گیرید (onResume). تلویزیون همیشه قابل مشاهده است، اما تعامل فقط با کنترل شروع می‌شود. اگر کسی تلویزیون را با پرده بپوشاند — صفحه دیگر قابل مشاهده نیست (onStop). اگر کنترل را از شما بگیرند — تعامل متوقف می‌شود (onPause)، اما تلویزیون همچنان قابل مشاهده است.

onResume چند وقت یکبار فراخوانی می‌شود؟

onResume هر بار که Activity فوکوس ورودی دریافت می‌کند فراخوانی می‌شود. حداقل تعداد — یک بار (در هنگام راه‌اندازی). حداکثر به سناریوهای استفاده بستگی دارد: جابجایی بین صفحات، باز کردن دیالوگ‌ها، قفل و باز کردن سریع دستگاه — هر سناریو هنگام بازگشت به صفحه onResume را فراخوانی می‌کند.

چرا onResume بهترین مکان برای باز کردن دوربین است؟

دوربین — منبع انحصاری است که فقط برای یک برنامه در یک زمان قابل دسترسی است. اگر دوربین را در onCreate یا onStart باز کنید، حتی زمانی که برنامه شما غیرفعال است برای سایر برنامه‌ها مسدود می‌ماند. onResume تضمین می‌کند که دوربین فقط زمانی باز است که Activity در پیش‌زمینه است و onPause بلافاصله آن را می‌بندد. این استاندارد توسعه Android است که در مستندات CameraX و Camera2 API تثبیت شده است.

آیا ممکن است onResume پس از onStart فراخوانی نشود؟

بله، اگر Activity بلافاصله پس از ظاهر شدن توسط Activity دیگری پوشانده شود، onResume رخ نمی‌دهد. به عنوان مثال، Activity A در متد onCreate یا onStart خود Activity B را راه‌اندازی می‌کند. در این حالت A onStart → onPause → onStop را دریافت می‌کند و onResume را رد می‌کند. سیستم onResume را فراخوانی نمی‌کند زیرا Activity A هرگز فوکوس ورودی دریافت نکرده است.

در onResume چه کارهایی نباید انجام داد؟

در onResume نمی‌توان عملیات همزمان طولانی انجام داد: بارگیری داده‌های بزرگ از شبکه، کوئری‌های پیچیده SQL، پردازش تصاویر. متد onResume در رشته UI کار می‌کند و هر مسدودیتی بیش از ۱۰۰–۲۰۰ میلی‌ثانیه منجر به تأخیر در پاسخگویی رابط می‌شود. همه عملیات سنگین باید ناهمزمان باشند — از طریق کوروتین‌ها، RxJava یا WorkManager. همچنین توصیه نمی‌شود بدون بررسی در onResume finish() فراخوانی کنید — این می‌تواند به یک حلقه بی‌نهایت بازآفرینی منجر شود.

خلاصه

  • onResume — حالت پیش‌زمینه با فوکوس ورودی; Activity آماده تعامل با کاربر است
  • منابع انحصاری — دوربین، میکروفون، ضبط ویدیو در onResume باز و در onPause بسته می‌شوند
  • onResume در مقابل onStart — onStart برای منابع قابل مشاهده، onResume برای منابع فعال; دیالوگ onResume را قطع می‌کند اما onStart را نه
  • سرعت — onResume باید سبک باشد; همه عملیات سنگین ناهمزمان
  • Fragment.onResume — به رویت‌پذیری در ViewPager بستگی دارد; userVisibleHint را بررسی کنید یا از setMaxLifecycle استفاده کنید
  • وظایف معمول — بازنشانی تایمر، به‌روزرسانی داده‌ها هنگام بازگشت، مدیریت BiometricPrompt
  • جفت onResume/onPause — منابع با دسترسی انحصاری منحصراً توسط این جفت مدیریت می‌شوند

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید