מגרשים וחבילות

האובייקטים Parcelable ו-Bundle מיועדים להיות בשימוש מעבר לגבולות של תהליכים, למשל באמצעות IPC/Binder טרנזקציות, בין פעילויות עם כוונות ולאחסן מצב זמני בכל הגדרה שינויים. בדף הזה מפורטות המלצות ושיטות מומלצות לשימוש Parcelable ו-Bundle אובייקטים.

הערה: התווית Parcel לא מיועדת לשימוש כללי מנגנונים מסדרת מנגנונים, לאחסן את כל נתוני Parcel בדיסק או לשלוח אותם דרך הרשת.

שליחת נתונים בין פעילויות

כשאפליקציה יוצרת אובייקט Intent לשימוש startActivity(android.content.Intent) בהתחלת פעילות חדשה, האפליקציה יכולה להעביר פרמטרים באמצעות putExtra(java.lang.String, java.lang.String) .

קטע הקוד הבא מציג דוגמה לאופן שבו לבצע את הפעולה הזו.

Kotlin

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

Java

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

מערכת ההפעלה חולקת את חבילת Bundle הבסיסית של ה-Intent. לאחר מכן, מערכת ההפעלה יוצרת את הפעילות החדשה, מפריד את הנתונים ומעביר את הכוונה לפעילות החדשה.

אנחנו ממליצים להשתמש במחלקה Bundle כדי להגדיר רכיבים המוכרים למערכת ההפעלה ב- Intent אובייקטים. הדירוג Bundle גבוה מאוד מותאמים במיוחד לסידורים וביטולי קרבות באמצעות חבילות.

במקרים מסוימים, ייתכן שתצטרכו מנגנון לשליחת אובייקטים מורכבים או מורכבים בין פעילויות. במקרים כאלה, הסיווג המותאם אישית צריך להטמיע 'Parcelable' ולספק את אמצעי תשלום אחד (writeToParcel(android.os.Parcel, int)). כמו כן, היא חייבת לספק שדה שאינו ריק בשם CREATOR, כוללת את הממשק Parcelable.Creator, createFromParcel() משמשת להמרה של Parcel בחזרה לאובייקט הנוכחי. לקבלת מידע נוסף, עיינו במשאבי העזרה של האובייקט Parcelable.

כששולחים נתונים באמצעות Intent, עליכם להקפיד להגביל את גודל הנתונים לכמה KB. שליחת יותר מדי נתונים עלולה לגרום למערכת חריג אחד (TransactionTooLargeException).

שליחת נתונים בין תהליכים

שליחת נתונים בין תהליכים דומה לשליחת נתונים בין פעילויות. עם זאת, כששולחים את בין תהליכים, מומלץ לא להשתמש במגרשים מותאמים אישית. אם שולחים אובייקט Parcelable מאפליקציה אחת לאחרת, צריך לוודא בדיוק אותה גרסה של המחלקה המותאמת אישית היא נמצא גם באפליקציה השולחת וגם באפליקציה המקבלת. בדרך כלל זו יכולה להיות ספרייה נפוצה בשימוש בשתי האפליקציות. יכולה לקרות שגיאה אם האפליקציה תנסה לשלוח מגרש בהתאמה אישית אל את המערכת, כי המערכת לא יכולה לפענח מחלקה שהיא לא יודעת עליו.

לדוגמה, אפליקציה יכולה להגדיר התראה באמצעות המחלקה AlarmManager, ומשתמשים ב-Parcelable בהתאמה אישית בכוונת ההתראה. כשההתראה מופעלת, המערכת משנה את פרטי הכוונה Bundle של תוספות להוספה וספירה חוזרת. שינוי זה עלול לגרום לכך שהמערכת תבטל את Parcelable מהתוספות. לאחר מכן, ההסרה יכולה לגרום לקרוס כשהוא מקבל את הכוונה ששונתה לשעון המעורר, מפני שהאפליקציה מצפה לקבל נתונים נוספים שכבר לא קיימים.

למאגר הנתונים הזמני של Binder יש גודל קבוע ומוגבל, כרגע 1MB, שמשותף לכל המשתמשים עסקאות שמתבצעות בתהליך התהליך. המגבלה הזאת נמצאת בתהליך במקום ברמת הפעילות, העסקאות האלה כוללות את כל העסקאות למשל, onSaveInstanceState, startActivity וכל אינטראקציה עם המערכת. כשגודל תבוצע חריגה מהמגבלה, הפעולה תטופל ללא ערך 'עסקה גדול מדי'.

במקרה הספציפי של savedInstanceState, צריך לשמור על כמות נתונים קטנה כי תהליך המערכת צריך לשמור את הנתונים שסופקו כל עוד יוכל אי פעם לנווט בחזרה לפעילות הזו (גם אם התהליך שבו הפעולה הופסקה). מומלץ לשמור את המצב השמור בפחות מ-50,000 נתונים.

הערה: ב-Android 7.0 (רמת API 24) ואילך, המערכת מחזירה חריגת transactionTooLiger כחריגה בסביבת זמן ריצה. בגרסאות קודמות של Android, המערכת מציגה אזהרה רק ב-Logcat.