onRestart — Android-এ Activity জীবনচক্রের একটি পদ্ধতি, যা সিস্টেম দ্বারা Activity-র Stopped অবস্থা থেকে Started অবস্থায় ফিরে আসার আগে আহ্বান করা হয়। onRestart সংকেত দেয় যে একটি Activity, পূর্বে অন্য স্ক্রিন দ্বারা লুকানো বা ব্যাকগ্রাউন্ডে ছোট করা, ব্যবহারকারীর জন্য আবার দৃশ্যমান হচ্ছে। onRestart-এ, ডেভেলপার পুরানো ডেটা আপডেট করে, তালিকা পুনরায় লোড করে এবং UI অবস্থা পুনরুদ্ধার করে যা Activity অদৃশ্য থাকাকালীন পরিবর্তিত হতে পারে। Google Android Vitals (2025) অনুসারে, onRestart ব্যবহার করে ডেটা আপডেট করা অ্যাপগুলি স্ক্রিনে ফিরে আসার সময় 25% কম ভুল তথ্য প্রদর্শন করে। Android Developers ডকুমেন্টেশন onRestart-কে Activity স্ক্রিনে আবার প্রদর্শিত হওয়ার আগে একটি প্রস্তুতিমূলক ধাপ হিসেবে বর্ণনা করে।
মূল বিষয়
onRestart — একটি কলব্যাক পদ্ধতি যা Android onStart-এর আগে আহ্বান করে যখন একটি Activity অদৃশ্য Stopped অবস্থা থেকে দৃশ্যমান হয়ে ফিরে আসে। এই পদ্ধতিটি অনন্য কারণ এটি কেবল তখনই আহ্বান করা হয় যখন Activity পুনরায় দেখানো হয় — ইনস্ট্যান্সের প্রথম তৈরি হওয়ার সময়, ক্রম onCreate দিয়ে শুরু হয়, onRestart বাদ দিয়ে। সম্পূর্ণ চক্র: onCreate → onStart → onResume (প্রথম লঞ্চ) বা onRestart → onStart → onResume (পরবর্তী প্রদর্শন)।
Android সিস্টেমের দৃষ্টিকোণ থেকে, onRestart একটি অপ্টিমাইজেশন যা Activity-কে তার ফিরে আসার জন্য প্রস্তুত হতে দেয়: রিপোজিটরি থেকে ডেটা আপডেট করা, UI অবস্থা সিঙ্ক্রোনাইজ করা, নেটওয়ার্ক সংযোগ পরীক্ষা করা। onResume-এর বিপরীতে, যা প্রতিবার Activity ফোকাস পাওয়ার সময় আহ্বান করা হয় (ডায়ালগ বা সিস্টেম মেনু থেকে ফিরে আসার সময়ও), onRestart শুধুমাত্র একটি পূর্ণ লুকানো-এবং-ফিরে আসা চক্রের সময় ট্রিগার হয়। এটি onRestart-কে “ভারী” আপডেট অপারেশনের জন্য আদর্শ স্থান করে তোলে যা আংশিক ফোকাস ক্ষতির সময় প্রয়োজন হয় না।
Android Activity জীবনচক্র স্পেসিফিকেশন অনুসারে, onStop এবং onRestart-এর মধ্যে সময়ের ব্যবধান কয়েক সেকেন্ড (ব্যবহারকারী দ্রুত সুইচ করেছে) থেকে কয়েক ঘন্টা (অ্যাপ ব্যাকগ্রাউন্ডে ছিল এবং ব্যবহারকারী ফিরেছে) পর্যন্ত হতে পারে। এই সময়ে, দূরবর্তী উৎসে (API, DB) ডেটা পরিবর্তিত হতে পারে, তাই onRestart সতেজতা পরীক্ষার জন্য একটি স্বাভাবিক বিন্দু।
onRestart শুধুমাত্র তখনই আহ্বান করা হয় যখন একটি Activity Stopped অবস্থা থেকে ফিরে আসে, যা Activity onStop আহ্বানের পরে প্রবেশ করেছিল। নীচে সমস্ত পরিস্থিতি দেওয়া হল যা onRestart-এর দিকে নিয়ে যায়।
onRestart আহ্বানের পরিস্থিতি:
কখন onRestart আহ্বান করা হয় না: স্ক্রিন রোটেশনের সময় (Activity ধ্বংস হয় এবং onCreate-এর মাধ্যমে পুনরায় তৈরি হয়), ডায়ালগ বক্স থেকে ফিরে আসার সময় (Activity onStop-এ যায় না, শুধু onPause → onResume), প্রসেস ডেথের সময় (Activity পুনরায় তৈরি হয়)।
onRestart এবং onCreate Activity পুনরুদ্ধারের দুটি ভিন্ন পদ্ধতি। তাদের মধ্যে পছন্দ নির্ভর করে Activity সম্পূর্ণরূপে ধ্বংস হয়েছিল নাকি শুধু লুকানো ছিল তার উপর।
| বৈশিষ্ট্য | onRestart | onCreate |
|---|---|---|
| কখন আহ্বান করা হয় | Activity Stopped থেকে ফিরে আসে | Activity প্রথমবার তৈরি হয় বা ধ্বংসের পরে |
| অবস্থা সংরক্ষিত | হ্যাঁ — ViewModel এবং ফিল্ডগুলি জীবিত | না — সবকিছু নতুন করে তৈরি হয় |
| Bundle | পাস করা হয় না | পাস করা হয় (savedInstanceState) |
| সাধারণ কার্য | ডেটা আপডেট, UI রিফ্রেশ | View ইনিশিয়ালাইজেশন, LiveData সাবস্ক্রিপশন |
| আহ্বানের ফ্রিকোয়েন্সি | প্রতিবার ফিরে আসার সময় | একবার বা ধ্বংসের পরে |
নির্বাচনের নিয়ম: View ইনিশিয়ালাইজেশন এবং LiveData/StateFlow সাবস্ক্রিপশন onCreate-এ করুন (বা Fragment-এর জন্য onViewCreated-এ)। ডেটা আপডেট, তালিকা পুনরায় লোড করা এবং অবস্থা পরীক্ষা — onRestart-এ। যদি ডেটা ViewModel-এর মাধ্যমে লোড করা হয়, onRestart কেবল ViewModel-এ refresh() পদ্ধতি কল করতে পারে, এবং View একটি রিঅ্যাকটিভ স্ট্রিমের মাধ্যমে আপডেট করা ডেটার সাবস্ক্রাইব করবে।
Google সুপারিশ করে: onRestart-এ onCreate-এর যুক্তি ডুপ্লিকেট করবেন না। ViewModel-এ refresh() পদ্ধতি বের করুন যা বর্তমান ডেটা লোড করে এবং সেগুলি onRestart-এ কল করুন। এটি পরিষ্কার MVVM আর্কিটেকচার সংরক্ষণ করে এবং কোড ডুপ্লিকেশন দূর করে।
onRestart সেই অপারেশনগুলির জন্য আদর্শ স্থান যা প্রতিবার স্ক্রিনে ফিরে আসার সময় সম্পাদন করা উচিত, কিন্তু প্রথম খোলার সময় প্রয়োজন হয় না। এখানে সাধারণ পরিস্থিতি দেওয়া হল:
viewModel.refreshItems() কল করুন।onRestart-এ কী করবেন না: Views পুনরায় আরম্ভ করবেন না — সেগুলি জীবিত কারণ Activity ধ্বংস হয়নি। LiveData-তে পুনরায় সাবস্ক্রাইব করবেন না — onCreate-এ সাবস্ক্রিপশন এখনও জীবিত। নতুন Fragments তৈরি করবেন না — সেগুলি ইতিমধ্যে FragmentManager-এ রয়েছে।
সবচেয়ে গুরুত্বপূর্ণ ব্যতিক্রম: onRestart আহ্বান করা হয় না যদি অ্যাপ প্রসেস সিস্টেম দ্বারা নিহত হয়। এটি একটি মূল বিষয় যা ডেভেলপাররা প্রায়ই অবস্থা পুনরুদ্ধারের জন্য onRestart-এর উপর নির্ভর করার সময় মিস করে।
প্রসেস ডেথের সময়:
কীভাবে এর থেকে রক্ষা করবেন: সর্বদা গুরুত্বপূর্ণ অবস্থা onSaveInstanceState(Bundle)-এ সংরক্ষণ করুন (onStop-এর আগে আহ্বান করা হয়) বা ViewModel-এ SavedStateHandle ব্যবহার করুন। onCreate-এ, savedInstanceState পরীক্ষা করুন: যদি এটি null না হয়, Bundle থেকে অবস্থা পুনরুদ্ধার করুন; যদি null হয়, তাজা ডেটা লোড করুন।
Google Android Vitals অনুসারে, ব্যাকগ্রাউন্ডে দীর্ঘ সময়ের পরে Activity-তে প্রায় 7% ফিরে আসা প্রসেস ডেথের পরে ঘটে। এর মানে হল যে প্রতি 15তম Activity যা onRestart আহ্বান করা উচিত ছিল, আসলে onCreate-এর মাধ্যমে যায়। এই পরিস্থিতি উপেক্ষা করা “ফিরে আসার পরে খালি স্ক্রিন” বাগগুলির অন্যতম প্রধান কারণ।
Activity সম্পাদনা স্ক্রিন থেকে ফিরে আসার পরে কাজের তালিকা আপডেট করতে onRestart-এ viewModel.refreshTasks() কল করে।
class TaskListActivity : AppCompatActivity() {
private val viewModel: TaskViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_task_list)
viewModel.tasks.observe(this) { tasks ->
Log.d("TaskList", "${tasks.size}টি কাজ প্রাপ্ত")
}
}
override fun onRestart() {
super.onRestart()
Log.d("TaskList", "onRestart: কাজের তালিকা আপডেট হচ্ছে")
viewModel.refreshTasks()
}
}
class TaskViewModel : ViewModel() {
private val _tasks = MutableLiveData<List<Task>>()
val tasks: LiveData<List<Task>> get() = _tasks
fun refreshTasks() {
viewModelScope.launch {
_tasks.value = TaskRepository().getAllTasks()
}
}
}
ViewModel.refreshTasks() রিপোজিটরি থেকে বর্তমান ডেটা লোড করে। LiveData স্বয়ংক্রিয়ভাবে Activity-কে ডেটা পরিবর্তন সম্পর্কে জানায় — UI অতিরিক্ত কোড ছাড়াই আপডেট হয়। onRestart একটি নতুন সাবস্ক্রিপশন তৈরি করে না — এটি ইতিমধ্যে onCreate-এ সেটআপ করা হয়েছিল।
Activity ফিরে আসার সময় টোকেন বৈধতা পরীক্ষা করে এবং প্রয়োজন হলে লগইনে পুনঃনির্দেশ করে।
class ProfileActivity : AppCompatActivity() {
private val authManager = AuthManager()
private val launcher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { Log.d("Profile", "লগইন স্ক্রিন থেকে ফিরেছে") }
override fun onRestart() {
super.onRestart()
if (!authManager.isTokenValid()) {
Log.d("Profile", "টোকেন মেয়াদোত্তীর্ণ — লগইনে পুনঃনির্দেশিত")
launcher.launch(Intent(this, LoginActivity::class.java))
}
}
}
class AuthManager {
fun isTokenValid(): Boolean {
val expiry = SharedPreferencesManager().getTokenExpiry()
return System.currentTimeMillis() < expiry
}
}
যদি ব্যবহারকারী দীর্ঘ সময়ের জন্য অ্যাপটি ছোট করে এবং টোকেনের মেয়াদ শেষ হওয়ার পরে ফিরে আসে, onRestart তাদের লগইন স্ক্রিনে পুনঃনির্দেশ করবে। এটি মেয়াদোত্তীর্ণ টোকেন সহ অনুরোধ করার চেষ্টা করার সময় API ত্রুটিগুলি প্রতিরোধ করে। নোট: পরীক্ষাটি onRestart-এ, onResume-এ নয়, ডায়ালগ থেকে ফিরে আসার সময় অপ্রয়োজনীয় পরীক্ষা এড়াতে।
Fragment ডেটা আপডেট করতে LifecycleObserver-এর মাধ্যমে onRestart ব্যবহার করে।
class FeedFragment : Fragment() {
private val viewModel: FeedViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycle.addObserver(object : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_RESTART)
fun onRestart() {
Log.d("FeedFragment", "LifecycleObserver-এর মাধ্যমে onRestart")
viewModel.refreshFeed()
}
})
}
}
Fragment-এ onRestart ওভাররাইড করার পরিবর্তে, LifecycleObserver ব্যবহার করা হয় — একটি আরও নমনীয় পদ্ধতি যা উত্তরাধিকার ছাড়াই জীবনচক্র ইভেন্ট যুক্তি যুক্ত করতে দেয়। ViewLifecycleOwner নিশ্চিত করে যে observer View সুযোগের মধ্যে বাস করে (এটি onDestroyView-এর বেশি বাঁচে না)।
সচরাচর জিজ্ঞাস্য
onResume প্রতিবার আহ্বান করা হয় যখন Activity ফোকাস পায় — যার মধ্যে ডায়ালগ বা সিস্টেম মেনু থেকে ফিরে আসাও অন্তর্ভুক্ত (Activity onStop-এ যায়নি)। onRestart শুধুমাত্র Stopped অবস্থা থেকে ফিরে আসার সময় আহ্বান করা হয়, যখন Activity সম্পূর্ণরূপে লুকানো ছিল। onRestart “ভারী” আপডেটের জন্য একটি সংকীर्ण ইভেন্ট, যখন onResume হালকা অপারেশনের জন্য (শিরোনাম পরিবর্তন, সময় আপডেট)।
না, করা যাবে না। onRestart onStop-এর সাথে একটি যুগ্ম পদ্ধতি: onRestart শুধুমাত্র তখনই আহ্বান করা হয় যখন Activity onStop-এর মাধ্যমে গেছে। যদি Activity onStop-এ না যায় (যেমন, একটি ডায়ালগ বক্স খোলা হয়েছিল), তাহলে ফিরে আসার সময় onRestart আহ্বান করা হয় না — শুধু onResume।
এমুলেটরে Home (হোম বাটন) টিপুন — Activity ছোট হবে এবং onStop পাবে। তারপর রিসেন্ট অ্যাপস বা লঞ্চারের মাধ্যমে অ্যাপটি খুলুন — Activity onRestart → onStart → onResume পাবে। ডিবাগিংয়ের জন্য, onRestart-এ ব্রেকপয়েন্ট সহ Debug বা Activity ট্যাগ সহ Log.d ব্যবহার করুন।
onRestart-এ একটি অনাকাংক্ষিত ব্যতিক্রম Force Close ঘটাবে। সিস্টেম জীবনচক্র কলব্যাকে ব্যতিক্রমগুলি ধরে না। যদি onRestart এমন অপারেশন করে যা ব্যতিক্রম ছুঁড়তে পারে (try-catch ছাড়া নেটওয়ার্ক অনুরোধ, null View নিয়ে কাজ করা), সেগুলি try-catch-এ মোড়ানো করুন।
না। onRestart শুধুমাত্র জীবিত Activities-এর জন্য আহ্বান করা হয় যা Stopped অবস্থা থেকে ফিরে আসছে। onRestart-এ isFinishing() সর্বদা false হবে। isFinishing() পরীক্ষা করা onPause (ডেটা সংরক্ষণ) এবং onDestroy (পুনর্নির্মাণকে finish() থেকে আলাদা করা) এ অর্থপূর্ণ।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন