Parcelable 與 Bundle

ParcelableBundle 物件適合用於各種程序邊界 (例如處理 IPC/Binder 交易)、包含意圖的活動之間,以及在設定變更期間儲存暫時性狀態。本頁面提供使用 ParcelableBundle 物件的建議和最佳做法。

注意: Parcel 並非一般用途序列化機制,您一律不得在磁碟上儲存任何 Parcel 資料或透過網路傳送資料。

在活動之間傳送資料

當應用程式建立要在 startActivity(android.content.Intent) 中使用的 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);

OS 會包裹意圖的基礎 Bundle。接著,OS 就會建立新活動、解除資料剖析,並將意圖傳遞至新活動。

建議您使用 Bundle 類別,在 Intent 物件上設定 OS 已知的原始基本功能。Bundle 類別極度最佳化,適合使用 Parcel 處理和解除封送。

在某些情況下,您可能需要相關機制,在不同活動之間傳送複合或複雜的物件。在這種情況下,自訂類別應實作 Parcelable,並提供適當的 writeToParcel(android.os.Parcel, int) 方法。還必須提供名為 CREATOR 的非空值欄位,用於實作 Parcelable.Creator 介面,而 createFromParcel() 方法會用於將 Parcel 轉換回目前的物件。詳情請參閱 Parcelable 物件的參考說明文件。

透過意圖傳送資料時,您應小心地將資料大小限制為幾 KB。傳送過多資料可能會導致系統擲回 TransactionTooLargeException 例外狀況。

在程序之間傳送資料

在活動之間傳送資料的做法與在活動之間傳送類似。然而,在程序之間傳送時,建議您不要使用自訂 Parcel。如要將自訂 Parcelable 物件從某個應用程式傳送至另一個應用程式,請務必確認傳送和接收應用程式都有相同的自訂類別版本。這通常是兩個應用程式中使用的通用程式庫。如果應用程式嘗試將自訂 Parcelable 傳送至系統,則可能會發生錯誤,因為系統無法解除封套自身不知道的類別。

舉例來說,應用程式可以使用 AlarmManager 類別設定鬧鐘,並在鬧鐘意圖上使用自訂 Parcelable。鬧鐘響起時,系統會修改意圖的 Bundle 額外項目來新增重複計數。這項修改可能會導致系統從額外項目中移除自訂 Parcelable。如此一來,當應用程式收到經過修改的鬧鐘意圖時,可能會導致應用程式當機,因為應用程式預期會收到已不存在的額外資料。

Binder 交易緩衝區的大小有限,目前是 1 MB,由處理中的所有交易共用。由於此限制是在程序層級而非個別活動層級,因此這些交易會包括應用程式中的所有繫結器交易,例如 onSaveInstanceState、startActivity 以及與系統的任何互動。如果超過大小限制,系統會擲回 TransactionTooLargeException。

針對 savedInstanceState 的特定情況,您應減少資料量,因為只要使用者能夠返回該活動 (即使終止活動的程序),系統程序就必須保留所提供的資料。建議您將儲存狀態保持在 50,000 以下的資料。

注意:在 Android 7.0 (API 級別 24) 以上版本中,系統會擲回 TransactionTooLargeException 做為執行階段例外狀況。在較舊版本的 Android 中,系統只會在 logcat 中顯示警告。