Parcelable 和 Bundle 物件適用於跨程序界線,例如處理序間通訊 (IPC)/Binder 交易、意圖活動之間,以及儲存設定變更的暫時狀態。本頁提供使用 Parcelable 和 Bundle 物件的建議和最佳做法。
注意: Parcel 並非一般用途的序列化機制,您絕不應將任何 Parcel 資料儲存在磁碟上,或透過網路傳送。
在活動之間傳送資料
應用程式建立 Intent 物件,在 startActivity() 中啟動新 Activity 時,可使用 putExtra() 方法傳遞參數。
下列程式碼片段顯示如何執行這項作業。
val intent = Intent(this, MyActivity::class.java).apply { putExtra("media_id", "a1b2c3") // ... } startActivity(intent)
作業系統會封裝意圖的基礎 Bundle。然後,OS 會建立新活動、取消封送資料,並將意圖傳遞至新活動。
建議您使用 Bundle 類別,在 Intent 物件上設定 OS 已知的基本型別。Bundle 類別經過高度最佳化,可使用封包封送及取消封送。
在某些情況下,您可能需要在活動之間傳遞複雜物件,或將這些物件保留在 UI 狀態中。在這種情況下,自訂類別應實作 Parcelable。如果是採用 Kotlin 和 Jetpack Compose 的新式應用程式,建議使用 @Parcelize 註解。這會自動產生序列化邏輯,以便在使用 Bundle 時安全地處理資料。這與您使用 rememberSaveable 時的資料處理方式相同。如要進一步瞭解如何使用 @Parcelize,請參閱「Parcelable 實作項目產生器」。
透過 Intent 傳送資料時,請務必將資料大小限制在幾 KB 內。
傳送過多資料可能會導致系統擲回 TransactionTooLargeException 例外狀況。
在程序之間傳送資料
在程序之間傳送資料,與在活動之間傳送資料類似。不過,在程序之間傳送時,建議不要使用自訂可封送物件。如果您要從一個應用程式傳送自訂 Parcelable 物件到另一個應用程式,請務必確認傳送和接收應用程式都存在完全相同的自訂類別版本。通常這會是兩個應用程式共用的程式庫。如果應用程式嘗試將自訂可封送物件傳送至系統,可能會發生錯誤,因為系統無法還原它不認識的類別。
舉例來說,應用程式可能會使用 AlarmManager 類別設定鬧鐘,並在鬧鐘意圖中使用自訂 Parcelable。鬧鐘響起時,系統會修改意圖的額外 Bundle,加入重複次數。這項修改可能會導致系統從額外內容中移除自訂 Parcelable。如果應用程式收到經過修改的鬧鐘意圖,就會因為預期收到額外資料但實際並未收到,而導致應用程式當機。
Binder 交易緩衝區的大小固定,目前為 1 MB,且程序中所有進行中的交易都會共用這個緩衝區。由於這項限制是針對程序層級,而非每個活動層級,因此這些交易包括應用程式中的所有繫結器交易,例如 startActivity、rememberSaveable (在幕後使用 onSaveInstanceState),以及與系統的任何互動。如果超過大小限制,系統會擲回 TransactionTooLargeException。
如果是使用 rememberSaveable 儲存狀態,資料量應盡量減少,因為系統程序必須保留提供的資料,直到使用者返回該活動為止 (即使活動程序已終止)。建議您將儲存的狀態資料量維持在 50 KB 以下。
注意:在 Android 7.0 (API 級別 24) 以上版本中,系統會擲回 TransactionTooLargeException 做為執行階段例外狀況。在較舊的 Android 版本中,系統只會在 Logcat 中顯示警告。