首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android onSaveInstanceState 保存 ArrayList 崩潰解析

     編輯:程式設計綜合問答

問題現象

在 onSaveInstanceState 中嘗試將 ArrayList<ProfileDetails> 強轉為 Parcelable 存入 Bundle,導致運行時崩潰。ArrayList 本身實作 Serializable,但不實作 Parcelable,無法直接用 putParcelable。

錯誤程式碼

// 錯誤寫法
savedInstanceState.putParcelable("Old", (Parcelable) profileDetails);  // ClassCastException

正確解決方案

方案一:使用 putSerializable(最簡單)

確認 ProfileDetails 實作 Serializable:

// 保存
savedInstanceState.putSerializable("Old", profileDetails);  // ArrayList 本身可序列化

// 恢復
profileDetails = (ArrayList) savedInstanceState.getSerializable("Old");

方案二:實作 Parcelable(高效能,推薦)

讓 ProfileDetails 實作 Parcelable,並使用 putParcelableArrayList:

// ProfileDetails 類別
data class ProfileDetails(...) : Parcelable {
    // 需實作 writeToParcel、CREATOR 等(Kotlin 用 @Parcelize 自動生成)
}

// 保存
savedInstanceState.putParcelableArrayList("Old", profileDetails)

// 恢復
profileDetails = savedInstanceState.getParcelableArrayList("Old")!!

常見誤區

  • ArrayList ≠ Parcelable:ArrayList 只實作 Serializable,強轉會崩潰。
  • 資料類別未實作介面:ProfileDetails 必須實作 Serializable 或 Parcelable,否則元素無法序列化。
  • 大量資料避免用 Bundle:Bundle 有大小限制(約 50KB),大列表建議用 ViewModel + SavedStateHandle 或本地快取。

現代最佳實踐

採用 ViewModel + SavedStateHandle 自動處理配置變更保存,程式碼更簡潔且不受 Bundle 大小限制:

class MyViewModel(handle: SavedStateHandle) : ViewModel() {
    var profileDetails: ArrayList = handle.get("Old") ?: arrayListOf()
        set(value) { handle["Old"] = value }
}

徹底理解序列化機制,選擇適合場景的方案,才能避免此類崩潰。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved