بسته ها و بسته ها

اشیاء Parcelable و Bundle برای استفاده در مرزهای فرآیند مانند تراکنش‌های IPC/Binder، بین فعالیت‌های دارای intent و برای ذخیره حالت گذرا در طول تغییرات پیکربندی در نظر گرفته شده‌اند. این صفحه توصیه‌ها و بهترین شیوه‌ها را برای استفاده از اشیاء Parcelable و Bundle ارائه می‌دهد.

توجه: Parcel یک مکانیزم سریال‌سازی عمومی نیست و شما هرگز نباید داده‌های Parcel را روی دیسک ذخیره کنید یا از طریق شبکه ارسال کنید.

ارسال داده بین اکتیویتی‌ها

وقتی یک برنامه یک شیء Intent برای استفاده در startActivity() در شروع یک Activity جدید ایجاد می‌کند، برنامه می‌تواند پارامترها را با استفاده از متد putExtra() ارسال کند.

قطعه کد زیر نمونه‌ای از نحوه انجام این عملیات را نشان می‌دهد.

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

سیستم عامل، Bundle مربوط به intent را بسته‌بندی می‌کند. سپس، سیستم عامل activity جدید را ایجاد می‌کند، داده‌ها را از بسته‌بندی خارج می‌کند و intent را به activity جدید ارسال می‌کند.

توصیه می‌کنیم از کلاس Bundle برای تنظیم مقادیر اولیه‌ای که سیستم عامل روی اشیاء Intent می‌شناسد استفاده کنید. کلاس Bundle برای مرتب‌سازی و نامرتب‌سازی با استفاده از بسته‌ها بسیار بهینه شده است.

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

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

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

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

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

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

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

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