onRestart — استعادة Activity في دورة الحياة

المؤلف: IT Sectr نُشر: 2026-03-04 وقت القراءة: 8 دق

onRestart — طريقة من دورة حياة Activity في Android، يستدعيها النظام قبل عودة Activity من الحالة Stopped إلى الحالة Started. تشير onRestart إلى أن Activity، التي كانت مخفية سابقاً بشاشة أخرى أو مصغرة إلى الخلفية، أصبحت مرئية للمستخدم مرة أخرى. في onRestart، يقوم المطور بتحديث البيانات القديمة وإعادة تحميل القوائم واستعادة حالة واجهة المستخدم التي ربما تغيرت بينما كانت Activity غير مرئية. وفقاً لـ Google Android Vitals (2025)، فإن التطبيقات التي تستخدم onRestart لتحديث البيانات تظهر 25% حالات أقل من عرض غير صحيح للمعلومات عند العودة إلى الشاشة. توثيق Android Developers يصف onRestart كخطوة تحضيرية قبل ظهور Activity على الشاشة مرة أخرى.

الخلاصة

  • onRestart يُستدعى عندما تعود Activity من الحالة Stopped، قبل onStart و onResume.
  • onRestart لا يُستدعى عند إنشاء Activity لأول مرة — فقط عند عرضها مرة أخرى بعد إخفائها.
  • الغرض الرئيسي من onRestart هو تحديث البيانات التي ربما تغيرت بينما كانت Activity غير مرئية.
  • onRestart لا يُستدعى أثناء إنهاء العملية — في هذه الحالة، يتم إعادة إنشاء Activity عبر onCreate.
  • الاستخدام الصحيح لـ onRestart يحسن تجربة المستخدم أثناء تعدد المهام والتبديل بين التطبيقات.

onRestart — جوهر الطريقة في دورة حياة Android

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: الشروط والتسلسل

onRestart يُستدعى فقط عندما تعود Activity من الحالة Stopped، والتي دخلتها Activity بعد استدعاء onStop. فيما يلي جميع السيناريوهات التي تؤدي إلى onRestart.

سيناريوهات استدعاء onRestart:

  • العودة من Activity أخرى — فتح المستخدم Activity جديدة (مثلاً، نقر على إشعار) ثم عاد للخلف (ضغط «رجوع»). المكدس: MainActivity.onPause → MainActivity.onStop → يتم إنشاء SecondActivity → يضغط المستخدم «رجوع» → SecondActivity.onPause → SecondActivity.onStop → SecondActivity.onDestroy → MainActivity.onRestart → MainActivity.onStart → MainActivity.onResume.
  • العودة من التصغير — صغر المستخدم التطبيق (الصفحة الرئيسية) وبعد فترة عاد. CurrentActivity.onPause → CurrentActivity.onStop → (التطبيق في الخلفية) → يعود المستخدم → CurrentActivity.onRestart → CurrentActivity.onStart → CurrentActivity.onResume.
  • العودة من شاشة القفل — شاشة القفل تغطي Activity؛ بعد فتح القفل، تستلم Activity onRestart إذا مر وقت طويل (أكثر من 5 ثوانٍ).
  • العودة من تطبيق تم تشغيله عبر Intent — الكاميرا، المعرض، المتصفح — أي تطبيق طرف ثالث تم تشغيله عبر startActivityForResult() أو ActivityResultLauncher.

متى لا يُستدعى onRestart: أثناء تدوير الشاشة (يتم تدمير Activity وإعادة إنشائها عبر onCreate)، عند العودة من مربع حوار (لا تدخل Activity في onStop، فقط onPause → onResume)، أثناء إنهاء العملية (يتم إعادة إنشاء Activity).

onRestart مقابل onCreate: أيهما تختار

onRestart و onCreate هما نهجان مختلفان لاستعادة Activity. يعتمد الاختيار بينهما على ما إذا كانت Activity قد دُمّرت بالكامل أو تم إخفاؤها ببساطة.

الخاصيةonRestartonCreate
متى يُستدعىActivity تعود من StoppedActivity تُنشأ لأول مرة أو بعد التدمير
الحالة محفوظةنعم — 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: تحديث البيانات وواجهة المستخدم

onRestart هو المكان المثالي للعمليات التي يجب تنفيذها في كل مرة يتم فيها العودة إلى الشاشة، ولكنها غير ضرورية عند الفتح الأول. إليك السيناريوهات النموذجية:

  • تحديث قائمة من قاعدة البيانات أو API — ذهب المستخدم إلى Activity أخرى، غير البيانات هناك، عاد — يجب أن تكون القائمة محدثة. استدع viewModel.refreshItems() في onRestart.
  • التحقق من التفويض — إذا كانت Activity مخفية لفترة طويلة، قد يكون رمز الوصول قد انتهت صلاحيته. onRestart هي نقطة التحقق من صحة الرمز وإعادة التوجيه إلى شاشة تسجيل الدخول.
  • مزامنة حالة واجهة المستخدم — تبديل السمة، تغيير اللغة، تحديث الإعدادات — يجب أن تنطبق التغييرات عند العودة إلى الشاشة.
  • إعادة تحميل الوسائط — إذا كانت Activity تعرض محتوى قد يتغير (خلاصة أخبار، أسعار عملات، طقس)، قم بتحديث البيانات في onRestart.
  • التحقق من اتصال الشبكة — عند العودة من وضع عدم الاتصال، يجب على Activity التحقق من توفر الشبكة وتبديل واجهة المستخدم.
  • استعادة الرسوم المتحركة — الرسوم المتحركة التي تم تحريرها في onStop يجب إعادة تشغيلها في onRestart قبل onStart.

ما لا يجب فعله في onRestart: لا تعِد تهيئة Views — فهي حية لأن Activity لم تُدمر. لا تعِد الاشتراك في LiveData — الاشتراك في onCreate لا يزال حياً. لا تنشئ Fragments جديدة — فهي موجودة بالفعل في FragmentManager.

onRestart وإنهاء العملية: استثناء مهم

أهم استثناء: onRestart لا يُستدعى إذا تم إنهاء عملية التطبيق بواسطة النظام. هذه نقطة رئيسية غالباً ما يغفلها المطورون عند الاعتماد على onRestart لاستعادة الحالة.

أثناء إنهاء العملية:

  • كان التطبيق في الخلفية، قام Android بإنهاء العملية لتحرير الذاكرة.
  • يعود المستخدم — يبدأ النظام عملية جديدة.
  • يتم إعادة إنشاء Activity: onCreate(Bundle) → onStart → onResume.
  • onRestart لا يُستدعى — بالنسبة للنظام، هذا مثيل جديد لـ Activity.

كيف تحمي نفسك من هذا: احفظ دائماً الحالة الحرجة في onSaveInstanceState(Bundle) (يُستدعى قبل onStop) أو استخدم SavedStateHandle في ViewModel. في onCreate، تحقق من savedInstanceState: إذا لم يكن null، استعد الحالة من Bundle؛ إذا كان null، قم بتحميل بيانات جديدة.

وفقاً لـ Google Android Vitals، حوالي 7% من العوائد إلى Activity بعد وقت طويل في الخلفية تحدث بعد إنهاء العملية. هذا يعني أن كل 15 Activity كان يجب أن تستدعي onRestart تمر في الواقع عبر onCreate. تجاهل هذا السيناريو هو أحد الأسباب الرئيسية لأخطاء «شاشة فارغة بعد العودة».

أمثلة كود مع onRestart بلغة Kotlin

مثال 1: onRestart مع تحديث القائمة عبر ViewModel

تستدعي Activity طريقة viewModel.refreshTasks() في onRestart لتحديث قائمة المهام بعد العودة من شاشة التحرير.

kotlin
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.

مثال 2: onRestart مع التحقق من التفويض

تتحقق Activity من صحة الرمز عند العودة وتُعيد التوجيه إلى تسجيل الدخول إذا لزم الأمر.

kotlin
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، لتجنب التحقق غير الضروري عند العودة من حوار.

مثال 3: onRestart في Fragment مع ViewLifecycleOwner

يستخدم Fragment onRestart عبر LifecycleObserver لتحديث البيانات.

kotlin
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).

الأسئلة الشائعة

ما الفرق بين onRestart و onResume؟

onResume يُستدعى في كل مرة تحصل فيها Activity على التركيز — بما في ذلك عند العودة من حوار أو قائمة نظام (لم تدخل Activity في onStop). onRestart يُستدعى فقط عند العودة من الحالة Stopped، عندما كانت Activity مخفية بالكامل. onRestart حدث أضيق للتحديثات «الثقيلة»، بينما onResume للعمليات الخفيفة (تغيير العنوان، تحديث الوقت).

هل يمكن استدعاء onRestart بدون onStop؟

لا، لا يمكن. onRestart هي طريقة مزدوجة مع onStop: onRestart يُستدعى فقط بعد أن تمر Activity عبر onStop. إذا لم تدخل Activity في onStop (مثلاً، تم فتح مربع حوار)، فعند العودة لا يُستدعى onRestart — فقط onResume.

كيف نحاكي onRestart في المحاكي؟

اضغط Home (زر المنزل) في المحاكي — سيتم تصغير Activity وستستلم onStop. ثم افتح التطبيق عبر التطبيقات الأخيرة أو المشغل — ستستلم Activity onRestart → onStart → onResume. للتصحيح، استخدم Debug مع نقاط توقف في onRestart أو Log.d مع علامة Activity.

ماذا يحدث إذا تم طرح استثناء في onRestart؟

استثناء غير مُعالج في onRestart سيسبب Force Close. النظام لا يلتقط الاستثناءات في استدعاءات دورة الحياة. إذا كانت onRestart تنفذ عمليات قد تطرح استثناء (طلب شبكة بدون try-catch، العمل مع View بقيمة null)، فلفها في try-catch.

هل أحتاج للتحقق من isFinishing() في onRestart؟

لا. onRestart يُستدعى فقط لـ Activities الحية التي تعود من الحالة Stopped. isFinishing() في onRestart سيكون دائماً false. التحقق من isFinishing() له معنى في onPause (حفظ البيانات) و onDestroy (التمييز بين إعادة الإنشاء والإنهاء).

الملخص

  • onRestart — طريقة دورة حياة تُستدعى عندما تعود Activity من الحالة Stopped، قبل onStart و onResume.
  • onRestart لا يُستدعى عند إنشاء Activity لأول مرة — فقط عند عرضها مرة أخرى بعد إخفائها بالكامل.
  • الغرض الرئيسي من onRestart هو تحديث البيانات القديمة والتحقق من الحالة (الرمز، الشبكة، الإعدادات).
  • onRestart لا يُستدعى أثناء إنهاء العملية — استخدم onCreate مع Bundle للاستعادة بعد إنهاء العملية.
  • لا تكرر منطق onCreate في onRestart: قم بالتهيئة في onCreate، والتحديثات في onRestart.
  • لـ Fragment، استخدم LifecycleObserver على viewLifecycleOwner بدلاً من تجاوز onRestart.
  • التنفيذ الصحيح لـ onRestart يحسن تجربة المستخدم أثناء تعدد المهام ويمنع عرض بيانات قديمة.

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا