繁体   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