将包含不可序列化对象的HashMap传递给另一个Fragment



这是我的非序列化类:

class Foo(val foo: String)

当我试图把它作为一个参数时,它不会编译:

MainFragment().apply {
arguments = Bundle().apply {
val foo = Foo("foo!")
putSerializable("key", foo) // compile error
}
}

但是如果我把它放进一个HashMap中,那么我就可以把HashMap作为一个参数:

MainFragment().apply {
arguments = Bundle().apply {
val foo = Foo("foo!")
val hashMap = hashMapOf("foo" to foo)
putSerializable("key", hashMap) // compile
}
}

当我在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
}

而且它在配置更改期间也能存活下来。为什么?

自答

事实证明,当应用程序进入后台时,我的应用程序出现了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)

我想实际的序列化是由ActivityManager在应用程序进入后台时进行的,而不是片段创建或配置更改。因为ActivityManager通过IPC技术处理序列化的Bundle,以处理应用程序的进程死亡和重新创建。

最新更新