Nik*_*dze 4 java android fragment parcelable screen-rotation
我想在屏幕旋转期间保留复杂的java对象,所以我使对象Parcelable并实现了必要的方法:
然后在Fragment的onSaveInstanceState中我保存了Parcelable:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable("myObject", myObject);
}
Run Code Online (Sandbox Code Playgroud)
并在Fragment的onCreate中得到了我的对象:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyObject myObject = savedInstanceState.getParcelable("myObject");
}
Run Code Online (Sandbox Code Playgroud)
这非常有效.
然后我做了一个测试:
当我运行应用程序时,我得到了完全相同的结果!我得到了一个包含所有适当值的对象.
这为何有效?Parcelable是否自动创建"Parcelable对象"?
是的,所以这与Bundle在内部处理缓存和分区的方式有关.当您调用时putParcelable(),它运行以下代码:
public void putParcelable(@Nullable String key, @Nullable Parcelable value) {
unparcel();
mMap.put(key, value);
mFdsKnown = false;
}
Run Code Online (Sandbox Code Playgroud)
所以基本上,a中的数据Bundle不会立即写入Parcel- mMap是一个ArrayMap<String, Object>并且它包含所有对象的缓存,Bundle因为它们被插入或移除.
在某些时候,writeToParcel()将被调用Bundle,此时所有内容都mMap被写入mParcelledData.
所以基本上,当你进行配置更改时,Bundle仍然没有写入a Parcel,所以你传入的对象的同一个实例仍然存储在Bundle's中mMap(所以你的对象也从未被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;
Run Code Online (Sandbox Code Playgroud)
因此,如果您要将Parcelable对象写入保存状态包,并将应用程序置于后台直到进程终止(或者我相信您可以通过运行强制执行adb shell am kill <application_id>)然后恢复,那么您将遇到问题数据未正确分配.
| 归档时间: |
|
| 查看次数: |
1746 次 |
| 最近记录: |