Parcelable و bundle

Parcelable and Bundle objects are intended to be used across process boundaries such as with IPC/Binder transactions, between activities with intents, and to store transient state across configuration changes. این صفحه توصیه‌ها و روال‌های مطلوب را برای استفاده از اشیاء 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 برای مرتب‌سازی و نامرتب‌سازی بااستفاده از بسته‌ها بسیار بهینه‌سازی شده است.

در برخی موارد، ممکن است لازم باشد اشیاء پیچیده را در فعالیت‌ها منتقل کنید یا آن‌ها را در حالت UI حفظ کنید. در چنین مواردی، کلاس سفارشی باید Parcelable را پیاده‌سازی کند. برای برنامه‌های مدرن Kotlin و Jetpack Compose، رویکرد توصیه‌شده استفاده از حاشیه‌نویسی @Parcelize است. این کار به‌طور خودکار منطق سریال‌سازی موردنیاز برای مدیریت ایمن داده‌هایتان را هنگام استفاده از «بسته‌ها» تولید می‌کند. این همان رویکردی است که برای مدیریت داده‌های شما هنگام استفاده از rememberSaveable به‌کار می‌رود. برای کسب اطلاعات بیشتر درباره استفاده از @Parcelize، تولیدکننده پیاده‌سازی Parcelable را ببینید.

هنگام ارسال داده ازطریق قصد، باید دقت کنید که اندازه داده را به چند کیلوبایت محدود کنید. ارسال داده‌های بیش‌ازحد می‌تواند باعث شود سیستم TransactionTooLargeException استثنا ایجاد کند.

ارسال داده بین فرایندها

ارسال داده بین فرایندها مشابه انجام این کار بین فعالیت‌ها است. بااین‌حال، هنگام ارسال بین فرایندها، توصیه می‌کنیم از parcelable سفارشی استفاده نکنید. اگر شیء سفارشی Parcelable را از برنامه‌ای به برنامه دیگر ارسال می‌کنید، باید مطمئن شوید که دقیقاً همان نسخه کلاس سفارشی در هر دو برنامه فرستنده و گیرنده وجود دارد. معمولاً این می‌تواند کتابخانه‌ای مشترک باشد که در هر دو برنامه استفاده می‌شود. اگر برنامه‌تان سعی کند parcelable سفارشی به سیستم ارسال کند، ممکن است خطایی رخ دهد، زیرا سیستم نمی‌تواند کلاسی را که از آن اطلاعی ندارد unmarshal کند.

برای مثال، ممکن است برنامه‌ای بااستفاده از کلاس AlarmManager زنگ ساعتی تنظیم کند و از Parcelable سفارشی در هدف زنگ ساعت استفاده کند. وقتی زنگ ساعت به‌صدا درمی‌آید، سیستم Bundle موارد اضافی هدف را اصلاح می‌کند تا تعداد تکرار را اضافه کند. این تغییر می‌تواند منجر به حذف Parcelable سفارشی از موارد اضافی توسط سیستم شود. این حذف به‌نوبه خود می‌تواند منجر به ازکار افتادن برنامه هنگام دریافت هدف زنگ ساعت اصلاح‌شده شود، زیرا برنامه انتظار دارد داده‌های اضافی را که دیگر وجود ندارد دریافت کند.

میان‌گیر تراکنش Binder اندازه ثابت محدودی دارد (درحال‌حاضر ۱ مگابایت) که بین همه تراکنش‌های درحال انجام برای فرایند هم‌رسانی می‌شود. ازآنجایی‌که این محدودیت در سطح فرایند است و نه در سطح فعالیت، این تراکنش‌ها شامل همه تراکنش‌های binder در برنامه می‌شود، مثل startActivity، rememberSaveable (که از onSaveInstanceState در پشت صحنه استفاده می‌کند)، و هرگونه تعامل با سیستم. وقتی از حد مجاز اندازه فراتر برود، TransactionTooLargeException ایجاد می‌شود.

در مورد خاص ذخیره کردن وضعیت با rememberSaveable، مقدار داده‌ها باید کم نگه داشته شود زیرا پردازش سیستم باید داده‌های ارائه‌شده را تا زمانی که کاربر بتواند به آن فعالیت برگردد (حتی اگر پردازش فعالیت متوقف شده باشد) نگه دارد. توصیه می‌کنیم که وضعیت ذخیره‌شده را به کمتر از ۵۰ کیلوبایت داده محدود کنید.

توجه: در Android نسخه ۷.۰ (سطح میانای برنامه‌سازی کاربردی ۲۴) و بالاتر، سیستم TransactionTooLargeException را به‌عنوان استثنای زمان اجرا برمی‌گرداند. در نسخه‌های پایین‌تر Android، سیستم فقط هشداری در logcat نشان می‌دهد.