简体   繁体   English

为什么即使我没有实现必要的功能,Parcelable 也能工作?

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

I wanted to retain a complex java object during screen rotation, so I made the object Parcelable and implemented necessary methods:我想在屏幕旋转期间保留一个复杂的 java 对象,所以我制作了对象 Parcelable 并实现了必要的方法:

  1. in writeToParcel(Parcel dest, int flags) method, I some saved values to "dest".在 writeToParcel(Parcel dest, int flags) 方法中,我将一些值保存到“dest”。
  2. in Parcelable.Creator's createFromParcel(Parcel source) method, I obtained the values from "source" in correct order and returned the appropriate object.在 Parcelable.Creator 的 createFromParcel(Parcel source) 方法中,我以正确的顺序从“源”中获取了值并返回了适当的对象。

Then in Fragment's onSaveInstanceState I saved the Parcelable:然后在 Fragment 的 onSaveInstanceState 中我保存了 Parcelable:

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

and got my object in Fragment's onCreate:并在 Fragment 的 onCreate 中获取我的对象:

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

This worked Perfectly.这非常有效。

Then I made the following test:然后我做了以下测试:

  1. Deleted all my code in writeToParcel method.删除了我在 writeToParcel 方法中的所有代码。
  2. Returned null in createFramParcel method.在 createFramParcel 方法中返回 null。

When I ran the app I got THE EXACT SAME RESULT.当我运行该应用程序时,我得到了完全相同的结果。 I got an object with all the appropriate values in it.我得到了一个包含所有适当值的对象。

Why did this work?为什么这样做? Does Parcelable create Parcelable objects "automatically"? Parcelable 是否“自动”创建 Parcelable 对象?

Yeah, so this has to do with the way Bundle handles caching and parceling internally.是的,所以这与 Bundle 在内部处理缓存和打包的方式有关。 When you call putParcelable() , it runs the following code:当您调用putParcelable()时,它会运行以下代码:

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

So basically, data in a Bundle is not immediately written to a Parcel -- mMap is an ArrayMap<String, Object> and it contains a cache of all the objects in the Bundle as they're inserted or removed.所以基本上, Bundle中的数据不会立即写入Parcel —— mMap是一个ArrayMap<String, Object>并且它包含Bundle中插入或删除的所有对象的缓存。

At some point, writeToParcel() will be called on the Bundle , at which point everything in mMap gets written into mParcelledData .在某个时候,将在Bundle上调用writeToParcel() ,此时mMap中的所有内容都将写入mParcelledData中。

So basically, when you do a config change, the Bundle still hasn't been written to a Parcel , so the same instance of the object you passed in is still stored in the Bundle 's mMap (so your Object also has never had writeToParcel() invoked -- you can confirm this by asserting that the object before and after config change have the same System.identityHashCode() ).所以基本上,当您进行配置更改时, Bundle仍未写入Parcel ,因此您传入的对象的相同实例仍存储在BundlemMap (因此您的 Object 也从未有过writeToParcel()调用——您可以通过断言配置更改前后的对象具有相同的System.identityHashCode()来确认这一点。

You can see notes about this in BaseBundle :你可以在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;

So if you were to write your Parcelable object to the save state bundle, and put your app in the background until the process dies (or I believe you can force that by running adb shell am kill <application_id> ) and then resume, you'll then run into the problem where your data isn't parceled correctly.因此,如果您要将Parcelable对象写入保存状态包,并将您的应用程序置于后台直到进程结束(或者我相信您可以通过运行adb shell am kill <application_id>强制执行此操作)然后恢复,您然后,您会遇到数据未正确打包的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么FileWriter会覆盖文件,即使我确实指定了文件追加 - Why does FileWriter overwrite the file even though I did specify it should append 为什么我的 Dijkstra 算法适用于负权重? 我是否错误地实现了它并且我是否牺牲了运行时间? - Why does my Dijkstra algorithm work for negative weights? Did I implement it incorrectly and am I sacrificing runtime? 为什么我的 2-D 角色向上移动,即使我什至没有按下任何键? - Why my 2-D character moves up, even though I did not even pressed keys? 即使我覆盖了抽象的所有内容,获取也不会覆盖错误 - Getting does not override error even though i did override everything that was abstract 为什么即使我声明了 rand,它也会给我一个错误? - Why does it give me an error even though I declared rand? 为什么这个类编译即使它没有正确实现其接口? - Why does this class compile even though it does not properly implement its interface? Eclipse连接到Web,即使我没有指定必要的代理 - Eclipse connects to web even though I have not specified necessary proxy 为什么即使在语法上正确,此powermock也不起作用? - Why will this powermock not work even though it is syntactically correct? 在休眠状态下,即使我将层叠类型设置为ALL,但是为什么删除时仍收到外键冲突异常? - In hibernate even though I set cascade type to ALL, but why did I still receive a foreign key violation exception when deleting? “数据库被锁定”即使我调用了database.close() - “Database is locked” Even though I did call database.close()
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM