onRestart — طريقة من دورة حياة Activity في Android، يستدعيها النظام قبل عودة Activity من الحالة Stopped إلى الحالة Started. تشير onRestart إلى أن Activity، التي كانت مخفية سابقاً بشاشة أخرى أو مصغرة إلى الخلفية، أصبحت مرئية للمستخدم مرة أخرى. في onRestart، يقوم المطور بتحديث البيانات القديمة وإعادة تحميل القوائم واستعادة حالة واجهة المستخدم التي ربما تغيرت بينما كانت 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 بالتحضير لعودتها: تحديث البيانات من المستودع، مزامنة حالة واجهة المستخدم، التحقق من اتصال الشبكة. على عكس onResume، الذي يُستدعى في كل مرة تحصل فيها Activity على التركيز (بما في ذلك عند العودة من حوار أو قائمة نظام)، يتم تشغيل onRestart فقط أثناء دورة كاملة من الإخفاء والعودة. هذا يجعل onRestart المكان المثالي لعمليات التحديث «الثقيلة» غير اللازمة أثناء فقدان التركيز الجزئي.
وفقاً لمواصفات دورة حياة Activity في Android، يمكن أن تتراوح الفترة الزمنية بين onStop و onRestart من بضع ثوانٍ (المستخدم بدّل بسرعة) إلى عدة ساعات (كان التطبيق في الخلفية وعاد المستخدم). خلال هذا الوقت، قد تكون البيانات في مصدر بعيد (API، قاعدة بيانات) قد تغيرت، لذا فإن 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) |
| الإجراءات النموذجية | تحديث البيانات، تحديث واجهة المستخدم | تهيئة View، الاشتراك في LiveData |
| تكرار الاستدعاء | كل مرة عند العودة | مرة واحدة أو بعد التدمير |
قاعدة الاختيار: قم بتهيئة View والاشتراك في LiveData/StateFlow في onCreate (أو onViewCreated للـ Fragment). تحديثات البيانات وإعادة تحميل القوائم والتحقق من الحالة — في onRestart. إذا تم تحميل البيانات عبر ViewModel، يمكن لـ onRestart ببساطة استدعاء طريقة refresh() على ViewModel، وستشترك View في البيانات المحدثة عبر تدفق تفاعلي.
توصي Google: لا تكرر منطق onCreate في onRestart. استخرج طرق refresh() في ViewModel التي تحمل البيانات الحالية، واستدعها في onRestart. هذا يحافظ على هندسة MVVM نظيفة ويزيل تكرار الكود.
onRestart هو المكان المثالي للعمليات التي يجب تنفيذها في كل مرة يتم فيها العودة إلى الشاشة، ولكنها غير ضرورية عند الفتح الأول. إليك السيناريوهات النموذجية:
viewModel.refreshItems() في onRestart.ما لا يجب فعله في onRestart: لا تعِد تهيئة Views — فهي حية لأن Activity لم تُدمر. لا تعِد الاشتراك في LiveData — الاشتراك في onCreate لا يزال حياً. لا تنشئ Fragments جديدة — فهي موجودة بالفعل في FragmentManager.
أهم استثناء: onRestart لا يُستدعى إذا تم إنهاء عملية التطبيق بواسطة النظام. هذه نقطة رئيسية غالباً ما يغفلها المطورون عند الاعتماد على onRestart لاستعادة الحالة.
أثناء إنهاء العملية:
كيف تحمي نفسك من هذا: احفظ دائماً الحالة الحرجة في onSaveInstanceState(Bundle) (يُستدعى قبل onStop) أو استخدم SavedStateHandle في ViewModel. في onCreate، تحقق من savedInstanceState: إذا لم يكن null، استعد الحالة من Bundle؛ إذا كان null، قم بتحميل بيانات جديدة.
وفقاً لـ Google Android Vitals، حوالي 7% من العوائد إلى Activity بعد وقت طويل في الخلفية تحدث بعد إنهاء العملية. هذا يعني أن كل 15 Activity كان يجب أن تستدعي onRestart تمر في الواقع عبر onCreate. تجاهل هذا السيناريو هو أحد الأسباب الرئيسية لأخطاء «شاشة فارغة بعد العودة».
تستدعي Activity طريقة viewModel.refreshTasks() في onRestart لتحديث قائمة المهام بعد العودة من شاشة التحرير.
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 تلقائياً بتغيرات البيانات — يتم تحديث واجهة المستخدم بدون كود إضافي. 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 onRestart عبر LifecycleObserver لتحديث البيانات.
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", "onRestart عبر LifecycleObserver")
viewModel.refreshFeed()
}
})
}
}
بدلاً من تجاوز onRestart في Fragment، يُستخدم 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. للتصحيح، استخدم Debug مع نقاط توقف في onRestart أو Log.d مع علامة Activity.
استثناء غير مُعالج في onRestart سيسبب Force Close. النظام لا يلتقط الاستثناءات في استدعاءات دورة الحياة. إذا كانت onRestart تنفذ عمليات قد تطرح استثناء (طلب شبكة بدون try-catch، العمل مع View بقيمة null)، فلفها في try-catch.
لا. onRestart يُستدعى فقط لـ Activities الحية التي تعود من الحالة Stopped. isFinishing() في onRestart سيكون دائماً false. التحقق من isFinishing() له معنى في onPause (حفظ البيانات) و onDestroy (التمييز بين إعادة الإنشاء والإنهاء).
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.