简体   繁体   English

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM