[英]Passing a HashMap which contains non Serializable object to another Fragment
Here is my non Serializable class:这是我的非 Serializable 类:
class Foo(val foo: String)
When I try to put it as an arguments it won't compile:当我尝试将它作为参数时,它不会编译:
MainFragment().apply {
arguments = Bundle().apply {
val foo = Foo("foo!")
putSerializable("key", foo) // compile error
}
}
But If I put it into a HashMap then I can put the HashMap as an argument:但是如果我把它放到一个 HashMap 中,那么我可以把 HashMap 作为一个参数:
MainFragment().apply {
arguments = Bundle().apply {
val foo = Foo("foo!")
val hashMap = hashMapOf("foo" to foo)
putSerializable("key", hashMap) // compile
}
}
And when I try to get Foo
instance from the HashMap during Fragment creation, I'm expecting an error like NotSerializableException
because Foo
class is not serializable, but it works fine:当我在 Fragment 创建期间尝试从 HashMap 获取Foo
实例时,我期待像NotSerializableException
这样的错误,因为Foo
类不可序列化,但它工作正常:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val hashMap = arguments?.getSerializable("key") as HashMap<String, Foo> // unchecked cast warning
Log.d(TAG, "${hashMap["foo"]?.foo}") // It works fine without an exception
}
And it survives during the configuration changes as well.它在配置更改期间也能幸存下来。 Why?为什么?
Self answer自我回答
It turns out my app got the RuntimeException when the app goes to the background.事实证明,当应用程序进入后台时,我的应用程序得到了 RuntimeException。
java.lang.RuntimeException: Parcel: unable to marshal value com.example.serializationsample.ui.main.Foo@378ca1e
at android.os.Parcel.writeValue(Parcel.java:1799)
...
at android.app.IActivityTaskManager$Stub$Proxy.activityStopped(IActivityTaskManager.java:5112)
at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:145)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8154)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
I guess the actual serialization is happened by the ActivityManager
when an app goes to the background but not the fragment creation or the configuration changes.我猜当应用程序进入后台但不是片段创建或配置更改时, ActivityManager
会发生实际的序列化。 Because the ActivityManager
handles the serialized Bundle
via IPC technique to take care of the process death and re-creation of an app.因为ActivityManager
通过 IPC 技术处理序列化的Bundle
来处理应用程序的进程死亡和重新创建。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.