تطوير Android / دليل حلول تحريري
إصلاح فقد الحالة بعد التدوير أو إعادة العملية
حدد مالك الحالة وسيناريو الاستعادة قبل اختيار rememberSaveable أو ViewModel أو الحالة المحفوظة أو التخزين الدائم.
قاعدة معرفة للقراءة فقط · بلا تعليقات عامة
تعرّف على الأعراض
يُمسح النص بعد التدوير أو يختفي الاختيار عند العودة أو تُحمّل قائمة بسجل خاطئ بعد إعادة النظام للعملية. قد تصمد المسودة أمام التدوير ثم تختفي لاحقاً، ما يدل على نجاح الاحتفاظ عبر الإعداد وفشل استعادة العملية. سجل الرحلة بدقة بما فيها Back وإزالة المهمة والإيقاف الإجباري ومغادرة الوجهة ووضع التطبيق بالخلفية.
افهم الأسباب المحتملة
- يعاد إنشاء المتغير المحلي العادي، ويستمر remember ما دام مالك التركيب موجوداً، ويصمد ViewModel أمام تغييرات الإعداد المناسبة لا وفاة العملية. ترتبط الحالة المحفوظة باستعادة مهمة مدعومة وليست تخزيناً دائماً. وقد تعيد النسخ المكررة ونسخ ViewModel المنشأة يدوياً القيم للبداية حتى عندما تناسب الواجهة المختارة الحالة.
صنّف القيمة المفقودة وعمرها
دوّن كل قيمة: معرّف مختار أو نص مسودة أو تمرير أو سجل مؤكد أو رفع معلق. قرر ما يصمد أمام مغادرة التركيب وإعادة الإعداد ووفاة العملية وجلسة جديدة مقصودة. قد تستخدم القيم العابرة الصغيرة حالة قابلة للحفظ، وتنتمي حالة أعمال الشاشة إلى ViewModel مدار بالمالك، والسجلات والمسودات المهمة إلى التخزين الدائم. يمنع التصنيف نقل كل شيء إلى singleton يسبب تسرباً ويختفي مع العملية أيضاً.
احتفظ بمالك واحد واحفظ مدخلات صغيرة
لاستعلام بحث يملكه ViewModel يستطيع SavedStateHandle حفظ مدخل إعادة البناء الصغير عبر استعادة النظام المدعومة. احصل على ViewModel بمصنع يراعي الحالة المحفوظة أو تكامل حقن متصل بمالك التنقل أو النشاط الصحيح. لا تنشئه مباشرة داخل دالة تركيبية. يحفظ المثال استعلاماً؛ وينبغي إعادة نتائج القائمة من المستودع. لا تضع مجموعات ضخمة وصوراً في المقبض لمجرد سهولة تسلسلها.
class QueryViewModel(private val saved: SavedStateHandle) : ViewModel() {
val query: StateFlow<String> = saved.getStateFlow("query", "")
fun editQuery(value: String) { saved["query"] = value }
}
@Composable
fun QueryRoute(viewModel: QueryViewModel) {
val query by viewModel.query.collectAsStateWithLifecycle()
TitleField(title = query, onTitleChange = viewModel::editQuery)
}
استخدم استيرادات الحالة المحفوظة وlifecycle-runtime-compose وStateFlow وCompose. TitleField المكوّن بلا حالة داخلية في درس Compose. يجب أن يحصل المستدعي على QueryViewModel عبر المالك ومسار الإنشاء الصحيحين. هذا ليس تطبيقاً كاملاً.
أعد تحميل الحقيقة الحالية وعالج الغياب
قد يشير معرّف مستعاد إلى صف محذوف أو نطاق حساب مختلف. تحقق منه واستعلم من التخزين الحالي المصرح بدلاً من اعتماد كائن قديم كامل. احفظ التعديلات المؤكدة عند تثبيتها لا في onDestroy وحدها، فلا تُضمن قبل إنهاء العملية. إذا وجب صمود مسودة مهمة أمام إزالة المهمة أو جلسة جديدة فاحفظها دائماً بسياسة احتفاظ صريحة. الحالة المحفوظة وسيلة تعاف وليست ضمان دوام شاملًا.
تحقق من نجاح الإصلاح
أعد التدوير أولاً وتحقق من بقاء القيمة دون تحميل أو أحداث مكررة. اختبر منفصلاً إعادة النظام للعملية في بيئة Android مضبوطة مع حفظ المهمة، ثم استأنف وافحص الاختيار وسياسة المسودة والقاعدة الحالية. اختبر إزالة المهمة والإيقاف الإجباري كسيناريوهين مختلفين بتوقعات صريحة ولا تستخدمهما دليلاً على استعادة النظام المعتادة.
امنع تكرار المشكلة
- وثق أعمار الحالة بجانب عقد الميزة. اجعل القيم تنطلق من مالك واحد واستخدم هويات قوائم وتنقل ثابتة وضمّن إعادة الإنشاء والتعافي عند تغير الملكية. اختبر السجلات المفقودة وتغير الحساب أثناء الاستعادة إلى جانب النجاح.