onResume হল অ্যান্ড্রয়েডের একটি জীবনচক্র পদ্ধতি যা কল করা হয় যখন একটি Activity বা Fragment সামনের প্ল্যানে আসে এবং ইনপুট ফোকাস পায়। এই অবস্থায়, স্ক্রিন ব্যবহারকারীর সাথে মিথস্ক্রিয়ার জন্য প্রস্তুত থাকে: সমস্ত স্পর্শ ইভেন্ট, কী প্রেস এবং অঙ্গভঙ্গি এই উপাদানে নির্দেশিত হয়। onResume হল Activity-র কার্যকরী অবস্থা, যেখানে অ্যাপ্লিকেশন তার বেশিরভাগ সময় ব্যয় করে। এখানেই ক্যামেরা খোলা হয়, ভিডিও প্লেব্যাক শুরু হয়, বক্তৃতা শনাক্তকরণ শুরু হয়, এবং সেন্সর শ্রোতা নিবন্ধিত হয় যেগুলির একচেটিয়া অ্যাক্সেস প্রয়োজন। সম্পূর্ণ Activity জীবনচক্র সম্পর্কে আরও জানতে, নিবন্ধটি পড়ুন Activity Lifecycle।
মূল বিষয়
onResume — Activity জীবনচক্রের তৃতীয় পদ্ধতি, onStart-এর পরে কল করা হয়, যা সংকেত দেয় যে স্ক্রিন ব্যবহারকারীর সাথে সম্পূর্ণ মিথস্ক্রিয়ার জন্য প্রস্তুত। এই মুহূর্তে, Activity ব্যাক স্ট্যাকের শীর্ষে থাকে, সিস্টেম এটিতে সমস্ত ইনপুট ইভেন্ট নির্দেশ করে, এবং অ্যাপ্লিকেশন ব্যবহারকারীর সক্রিয় অংশগ্রহণের প্রয়োজন এমন যেকোনো অপারেশন শুরু করতে পারে: ভিডিও কল, গেম, অডিও রেকর্ডিং, Canvas-এ আঁকা।
onResume “অগ্রভাগের জীবনকাল” (foreground lifetime) এর অংশ — onResume এবং onPause-এর মধ্যে ব্যবধান। এটি Activity-র সবচেয়ে সক্রিয় সময়, যখন অ্যাপ্লিকেশন সর্বাধিক রিসোর্স ব্যবহার করে: স্পর্শ প্রক্রিয়াকরণের জন্য CPU, অ্যানিমেশন রেন্ডারিংয়ের জন্য GPU, ভিডিও ক্যাপচারের জন্য ক্যামেরা এবং মাইক্রোফোন। জীবনচক্রের এই স্তরটি বোঝা শক্তি খরচ অপ্টিমাইজ করার জন্য গুরুত্বপূর্ণ — onResume-এ খোলা রিসোর্সগুলি onPause-এ অবিলম্বে বন্ধ করতে হবে।
Google I/O 2025 অনুসারে, প্রতি সেশনে Activity onResume অবস্থায় যে গড় সময় ব্যয় করে তা সংবাদ অ্যাপ্লিকেশনের জন্য 2–5 মিনিট এবং গেম ও মেসেঞ্জারের জন্য 15–30 মিনিট। বাকি সময় 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", "Failed to bind camera", e)
}
}, ContextCompact.getMainExecutor(this))
}
override fun onPause() {
super.onPause()
cameraProvider?.unbindAll()
preview = null
}
}
CameraX উদাহরণটি onResume/onPause-এর ক্লাসিক ব্যবহার প্রদর্শন করে: ক্যামেরা একটি এক্সক্লুসিভ রিসোর্স যা এক সময়ে শুধুমাত্র একটি অ্যাপ্লিকেশন ব্যবহার করতে পারে। bindToLifecycle-এর মাধ্যমে ক্যামেরাকে জীবনচক্রের সাথে বাঁধলে onPause-এ ক্যামেরা স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যায়, কিন্তু স্পষ্ট unbindAll কল তাৎক্ষণিক মুক্তির নিশ্চয়তা দেয়। Activities-এর মধ্যে স্যুইচ করার সময় এটি বিশেষভাবে গুরুত্বপূর্ণ: ক্যামেরা মুক্ত করতে হবে অন্য Activity এটি খোলার চেষ্টা করার আগে।
Fragment-এ onResume কল করা হয় যে Activity তাকে ধারণ করে তার onResume পাওয়ার পরে। তবে, FragmentManager এবং ViewPager-এর বৈশিষ্ট্যগুলির কারণে, Fragment-এর জন্য onResume কলের সময় Activity-র সাপেক্ষে বিলম্বিত হতে পারে। উদাহরণস্বরূপ, offscreenPageLimit = 1 সহ ViewPager-এ একটি Fragment 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()
}
}
Fragment.onResume-এ userVisibleHint পরীক্ষা ViewPager-এর জন্য প্রাসঙ্গিক: Fragment onResume পেতে পারে কিন্তু প্রতিবেশী পৃষ্ঠা দ্বারা লুকানো থাকতে পারে (উদাহরণস্বরূপ, অ্যানিমেটেড ট্রানজিশনের সময়)। এই ধরনের ক্ষেত্রে, দৃশ্যমানতা পরীক্ষা না করে onResume-এ ভিডিও বা বায়োমেট্রিক্স শুরু করলে অপ্রত্যাশিত আচরণ হবে। Fragment 1.5.0 থেকে শুরু করে, ViewPager2-এ ফ্রাগমেন্ট জীবনচক্রের সঠিক নিয়ন্ত্রণের জন্য FragmentTransaction.setMaxLifecycle() ব্যবহার করার সুপারিশ করা হয়।
ডেভেলপাররা প্রায়শই onStart এবং onResume-কে গুলিয়ে ফেলেন, কোড ভুল পদ্ধতিতে রাখেন। প্রধান নিয়ম: onStart — দৃশ্যমান অবস্থায় কাজ করে এমন রিসোর্সের জন্য; onResume — যে রিসোর্সগুলির ইনপুট ফোকাস প্রয়োজন তাদের জন্য। আসুন নির্দিষ্ট পরিস্থিতি এবং সঠিক পদ্ধতি নির্বাচন দেখি।
| অপারেশন | পদ্ধতি | যুক্তি |
|---|---|---|
| ভৌগোলিক অবস্থান সাবস্ক্রিপশন | onStart / onStop | GPS আংশিক দৃশ্যমানতায় কাজ করতে পারে |
| ক্যামেরা খোলা | onResume / onPause | ক্যামেরা একটি এক্সক্লুসিভ রিসোর্স |
| BroadcastReceiver | onStart / onStop | সিস্টেম ইভেন্টগুলির ফোকাস প্রয়োজন নেই |
| ভিডিও প্লেব্যাক | onResume / onPause | ভিডিও ব্যবহারকারীর কাছে দৃশ্যমান হতে হবে |
| ব্লুটুথ স্ক্যানিং | onStart / onStop | স্ক্যানিং ব্যাকগ্রাউন্ডে চলতে পারে |
| ভয়েস রেকর্ডার (MediaRecorder) | onResume / onPause | রেকর্ডিংয়ের জন্য সক্রিয় UI প্রয়োজন |
| সেন্সর শ্রোতা | onResume / onPause | গেম এবং অঙ্গভঙ্গির জন্য সেন্সর |
| ডেটা আপডেট | onStart | প্রকাশিত হলে তাজা ডেটা প্রয়োজন |
একটি ব্যবহারিক নিয়ম: যদি কোনো অপারেশন ডায়ালগ প্রদর্শিত হলে বাধাপ্রাপ্ত হওয়া উচিত — onResume/onPause ব্যবহার করুন। যদি কোনো অপারেশন স্ক্রিন আংশিকভাবে ঢাকা থাকলেও চলতে পারে — onStart/onStop ব্যবহার করুন। উদাহরণস্বরূপ, একটি ভিডিও প্লেয়ারের ডায়ালগ খুললে ভিডিও থামানো উচিত (onPause), যখন ভৌগোলিক অবস্থান আপডেট চলতে পারে (onStart-এ থাকে)।
এক্সক্লুসিভ রিসোর্স হল ডিভাইসের এমন উপাদান যা একটি নির্দিষ্ট সময়ে শুধুমাত্র একটি অ্যাপ্লিকেশন ব্যবহার করতে পারে। ক্যামেরা, মাইক্রোফোন, ভিডিও আউটপুট (MediaProjection), রিড মোডে NFC অ্যাডাপ্টার, এক্সেসরি মোডে USB ডিভাইস — এই সমস্ত রিসোর্স 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 তাৎক্ষণিকভাবে এটি বন্ধ করে দেয়। এটি অ্যান্ড্রয়েড বিকাশের একটি মান, যা CameraX এবং Camera2 API ডকুমেন্টেশনে প্রতিষ্ঠিত।
হ্যাঁ, onResume নাও ঘটতে পারে যদি একটি Activity প্রকাশের পরপরই অন্য Activity দ্বারা আবৃত হয়ে যায়। উদাহরণস্বরূপ, Activity A, onCreate বা onStart পদ্ধতিতে Activity B শুরু করে। এই ক্ষেত্রে, A onStart → onPause → onStop পায়, onResume বাদ দিয়ে। সিস্টেম onResume কল করে না কারণ Activity A কখনও ইনপুট ফোকাস পায়নি।
onResume-এ, দীর্ঘ সিঙ্ক্রোনাস অপারেশন করা উচিত নয়: নেটওয়ার্ক থেকে বড় ডেটা লোড করা, জটিল SQL কোয়েরি, ইমেজ প্রসেসিং। onResume UI থ্রেডে চলে, এবং 100–200 মিলিসেকেন্ডের বেশি যেকোনো ব্লকিং ইন্টারফেস প্রতিক্রিয়ায় বিলম্ব ঘটায়। সমস্ত ভারী অপারেশন অ্যাসিঙ্ক্রোনাস হওয়া উচিত — coroutines, RxJava বা WorkManager-এর মাধ্যমে। পরীক্ষা না করে onResume-এ finish() কল করারও সুপারিশ করা হয় না — এটি পুনর্নির্মাণের অসীম লুপের কারণ হতে পারে।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন