簡體   English   中英

為什么即使我沒有實現必要的功能,Parcelable 也能工作?

[英]Why does Parcelable work even though I did not implement the necessary functions?

我想在屏幕旋轉期間保留一個復雜的 java 對象,所以我制作了對象 Parcelable 並實現了必要的方法:

  1. 在 writeToParcel(Parcel dest, int flags) 方法中,我將一些值保存到“dest”。
  2. 在 Parcelable.Creator 的 createFromParcel(Parcel source) 方法中,我以正確的順序從“源”中獲取了值並返回了適當的對象。

然后在 Fragment 的 onSaveInstanceState 中我保存了 Parcelable:

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putParcelable("myObject", myObject);
}

並在 Fragment 的 onCreate 中獲取我的對象:

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  MyObject myObject = savedInstanceState.getParcelable("myObject");
}

這非常有效。

然后我做了以下測試:

  1. 刪除了我在 writeToParcel 方法中的所有代碼。
  2. 在 createFramParcel 方法中返回 null。

當我運行該應用程序時,我得到了完全相同的結果。 我得到了一個包含所有適當值的對象。

為什么這樣做? Parcelable 是否“自動”創建 Parcelable 對象?

是的,所以這與 Bundle 在內部處理緩存和打包的方式有關。 當您調用putParcelable()時,它會運行以下代碼:

public void putParcelable(@Nullable String key, @Nullable Parcelable value) {
    unparcel();
    mMap.put(key, value);
    mFdsKnown = false;
}

所以基本上, Bundle中的數據不會立即寫入Parcel —— mMap是一個ArrayMap<String, Object>並且它包含Bundle中插入或刪除的所有對象的緩存。

在某個時候,將在Bundle上調用writeToParcel() ,此時mMap中的所有內容都將寫入mParcelledData中。

所以基本上,當您進行配置更改時, Bundle仍未寫入Parcel ,因此您傳入的對象的相同實例仍存儲在BundlemMap (因此您的 Object 也從未有過writeToParcel()調用——您可以通過斷言配置更改前后的對象具有相同的System.identityHashCode()來確認這一點。

你可以在BaseBundle中看到關於這個的注釋:

// Invariant - exactly one of mMap / mParcelledData will be null
// (except inside a call to unparcel)

ArrayMap<String, Object> mMap = null;

/*
 * If mParcelledData is non-null, then mMap will be null and the
 * data are stored as a Parcel containing a Bundle.  When the data
 * are unparcelled, mParcelledData willbe set to null.
 */
Parcel mParcelledData = null;

因此,如果您要將Parcelable對象寫入保存狀態包,並將您的應用程序置於后台直到進程結束(或者我相信您可以通過運行adb shell am kill <application_id>強制執行此操作)然后恢復,您然后,您會遇到數據未正確打包的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM