باقات قابلة للتقسيم

يُفترض استخدام كائنَي Parcelable وBundle ضمن حدود العمليات، مثلاً مع معاملات IPC/Binder، وبين الأنشطة باستخدام النوايا، ولتخزين الحالة المؤقتة عند تغيير الإعدادات. تقدّم هذه الصفحة اقتراحات وأفضل الممارسات لاستخدام كائنَي Parcelable وBundle.

ملاحظة: Parcel ليس آلية تسلسل للأغراض العامة، ويجب عدم تخزين أي بيانات Parcel على القرص أو إرسالها عبر الشبكة.

إرسال البيانات بين الأنشطة

عندما ينشئ تطبيق كائن Intent لاستخدامه في startActivity() لبدء نشاط جديد، يمكنه تمرير المَعلمات باستخدام طريقة putExtra().

يعرض مقتطف الرمز البرمجي التالي مثالاً على كيفية إجراء هذه العملية.

val intent = Intent(this, MyActivity::class.java).apply {
    putExtra("media_id", "a1b2c3")
    // ...
}
startActivity(intent)

يُقسّم نظام التشغيل Bundle الأساسي للنية. بعد ذلك، ينشئ نظام التشغيل النشاط الجديد، ويُعيد تجميع البيانات، ويمرّر النية إلى النشاط الجديد.

ننصحك باستخدام فئة Bundle لضبط القيم الأولية المعروفة لنظام التشغيل على كائنات Intent. تم تحسين فئة Bundle بشكل كبير لعمليات التجميع وإعادة التجميع باستخدام الحزم.

في بعض الحالات، قد تحتاج إلى تمرير كائنات معقّدة بين الأنشطة أو الاحتفاظ بها في حالة واجهة المستخدم. في هذه الحالات، يجب أن تنفّذ الفئة المخصّصة واجهة Parcelable. بالنسبة إلى تطبيقات Kotlin وJetpack Compose الحديثة، ننصحك باستخدام تعليق @Parcelize التوضيحي. يؤدي ذلك إلى إنشاء منطق التسلسل اللازم تلقائيًا للتعامل بأمان مع بياناتك عند استخدام حزم البيانات. هذا هو الأسلوب نفسه المستخدَم للتعامل مع بياناتك عند استخدام rememberSaveable. لمزيد من المعلومات حول استخدام @Parcelize, يُرجى الاطّلاع على أداة إنشاء تنفيذ Parcelable.

عند إرسال البيانات عبر نية، يجب الحرص على حصر حجم البيانات ببضعة كيلوبايت. قد يؤدي إرسال الكثير من البيانات إلى أن يعرض النظام استثناء TransactionTooLargeException.

إرسال البيانات بين العمليات

يشبه إرسال البيانات بين العمليات إرسالها بين الأنشطة. ومع ذلك، عند الإرسال بين العمليات، ننصحك بعدم استخدام كائنات Parcelable المخصّصة. إذا أرسلت كائن Parcelable مخصّصًا من تطبيق إلى آخر، عليك التأكّد من أنّ الإصدار نفسه من الفئة المخصّصة متوفّر في كلّ من التطبيقَين المُرسِل والمستلِم. يمكن أن تكون هذه عادةً مكتبة مشتركة مستخدَمة في كلا التطبيقَين. يمكن أن يحدث خطأ إذا حاول تطبيقك إرسال كائن Parcelable مخصّص إلى النظام، لأنّ النظام لا يمكنه إلغاء تجميع فئة لا يعرفها.

على سبيل المثال، قد يضبط تطبيق منبّهًا باستخدام فئة AlarmManager، ويستخدم كائن Parcelable مخصّصًا في نية المنبّه. عندما يرنّ المنبّه، يعدّل النظام Bundle الإضافات في النية لإضافة عدد التكرار. يمكن أن يؤدي هذا التعديل إلى أن يزيل النظام كائن Parcelable المخصّص من الإضافات. يمكن أن يؤدي هذا الإزالة بدوره إلى تعطُّل التطبيق عند تلقّيه نية المنبّه المعدَّلة، لأنّ التطبيق يتوقّع تلقّي بيانات إضافية لم تعُد متوفّرة.

يبلغ الحجم الثابت لمخزن معاملات Binder المؤقت حجمًا محدودًا، وهو حاليًا 1 ميغابايت، ويتم مشاركته بين جميع المعاملات قيد التقدّم للعملية. بما أنّ هذا الحدّ ينطبق على مستوى العملية وليس على مستوى النشاط، تتضمّن هذه المعاملات جميع معاملات Binder في التطبيق، مثل startActivity وrememberSaveable (الذي يستخدم onSaveInstanceState في الخلفية) وأي تفاعل مع النظام. عند تجاوز حدّ الحجم، يتم عرض TransactionTooLargeException.

في حالة حفظ الحالة باستخدام rememberSaveable، يجب أن يكون حجم البيانات صغيرًا لأنّ عملية النظام تحتاج إلى الاحتفاظ بالبيانات المقدَّمة طالما أنّ بإمكان المستخدِم الرجوع إلى هذا النشاط (حتى إذا تم إيقاف عملية النشاط). ننصحك بأن لا يتجاوز حجم الحالة المحفوظة 50 كيلوبايت من البيانات.

ملاحظة: في الإصدار Android 7.0 (مستوى واجهة برمجة التطبيقات 24) والإصدارات الأحدث، يعرض النظام TransactionTooLargeException كاستثناء في وقت التشغيل. في الإصدارات الأقدم من Android، يعرض النظام تحذيرًا فقط في logcat.