האובייקטים 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 פיתוח נייטיב, הגישה המומלצת היא להשתמש בהערה @Parcelize. המערכת יוצרת באופן אוטומטי את לוגיקת הסריאליזציה שנדרשת כדי לטפל בנתונים בצורה בטוחה כשמשתמשים ב-Bundles. זו אותה גישה שבה אנחנו משתמשים כדי לטפל בנתונים שלכם כשאתם משתמשים ב-rememberSaveable.
מידע נוסף על השימוש ב-@Parcelize זמין במאמר מחולל הטמעה של Parcelable.
כששולחים נתונים באמצעות Intent, חשוב להקפיד שהגודל של הנתונים לא יעלה על כמה קילו-בייט.
שליחת יותר מדי נתונים עלולה לגרום למערכת להחזיר TransactionTooLargeExceptionחריגה.
שליחת נתונים בין תהליכים
שליחת נתונים בין תהליכים דומה לשליחת נתונים בין פעילויות. עם זאת, כששולחים בין תהליכים, מומלץ לא להשתמש ב-parcelables בהתאמה אישית. אם שולחים אובייקט מותאם אישית מסוג Parcelable מאפליקציה אחת לאפליקציה אחרת, צריך לוודא שגרסה זהה של המחלקה המותאמת אישית קיימת באפליקציה השולחת ובאפליקציה המקבלת. בדרך כלל, מדובר בספרייה משותפת שמשמשת את שתי האפליקציות. יכולה להתרחש שגיאה אם האפליקציה מנסה לשלוח חבילה מותאמת אישית למערכת, כי המערכת לא יכולה לבטל את ה-marshaling של מחלקה שהיא לא מכירה.
לדוגמה, אפליקציה יכולה להגדיר שעון מעורר באמצעות המחלקה AlarmManager ולהשתמש ב-Parcelable מותאם אישית בכוונת השעון המעורר. כשההתראה מופעלת, המערכת משנה את Bundle של התוספים של הכוונה כדי להוסיף את מספר החזרות. השינוי הזה יכול לגרום למערכת להסיר את Parcelable המותאם אישית מהתוספים. ההסרה הזו עלולה לגרום לקריסת האפליקציה כשהיא מקבלת את כוונת השעון המעורר ששונתה, כי האפליקציה מצפה לקבל נתונים נוספים שכבר לא קיימים.
למאגר הנתונים הזמני של עסקאות Binder יש גודל קבוע מוגבל, כרגע 1MB, שמשותף לכל העסקאות בתהליך. המגבלה הזו היא ברמת התהליך ולא ברמת הפעילות, ולכן העסקאות האלה כוללות את כל העסקאות של Binder באפליקציה, כמו startActivity, rememberSaveable (שמשתמש ב-onSaveInstanceState מתחת לפני השטח) וכל אינטראקציה עם המערכת. אם חורגים ממגבלת הגודל, מוצגת שגיאה TransactionTooLargeException.
במקרה הספציפי של שמירת מצב באמצעות rememberSaveable, כמות הנתונים צריכה להיות קטנה כי תהליך המערכת צריך לשמור את הנתונים שסופקו כל עוד המשתמש יכול לחזור לפעילות הזו (גם אם התהליך של הפעילות הופסק).
מומלץ לשמור מצב עם פחות מ-50KB של נתונים.
הערה: ב-Android 7.0 (רמת API 24) ומעלה, המערכת יוצרת TransactionTooLargeException כחריגה בזמן ריצה.
בגרסאות ישנות יותר של Android, המערכת מציגה רק אזהרה ב-logcat.