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

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

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

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

هنگامی که یک برنامه یک شی Intent ایجاد می کند تا در startActivity(android.content.Intent) برای شروع یک فعالیت جدید استفاده کند، برنامه می تواند با استفاده از روش putExtra(java.lang.String, java.lang.String) پارامترها را ارسال کند.

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

کاتلین

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

جاوا

Intent intent = new Intent(this, MyActivity.class);
intent.putExtra("media_id", "a1b2c3");
// ...
startActivity(intent);

سیستم‌عامل بسته‌بندی Bundle هدف را بسته‌بندی می‌کند. سپس، سیستم‌عامل فعالیت جدید را ایجاد می‌کند، داده‌ها را بسته‌بندی می‌کند و هدف را به فعالیت جدید منتقل می‌کند.

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

در برخی موارد، ممکن است به مکانیزمی برای ارسال اشیاء مرکب یا پیچیده در میان فعالیت ها نیاز داشته باشید. در چنین مواردی، کلاس سفارشی باید Parcelable را پیاده سازی کند و متد مناسب writeToParcel(android.os.Parcel, int) را ارائه دهد. همچنین باید یک فیلد غیر تهی به نام CREATOR ارائه کند که رابط Parcelable.Creator پیاده سازی کند، که متد createFromParcel() آن برای تبدیل Parcel به شی فعلی استفاده می شود. برای اطلاعات بیشتر، به مستندات مرجع شیء Parcelable مراجعه کنید.

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

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

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

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

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

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

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