Android,Parcelable如何serialized/deserialized,是否维护对象实例的引用?

Android, how is the Parcelable serialized/deserialized, does it maintain the reference to the object instance?

有一个片段,它希望通过片段的参数传入一个 IDataProvider(可打包),并用它从存储库中获取数据。

这是 DataFragment,它通过 bundle.getParcelable<Parcelable>(KEY_DATA_PROVIDER) as? IDataProvider

从参数中检索 dataProvider
    class DataFragment: Fragment() {

        interface IDataProvider : Parcelable {
            fun getDataByUUID(uuid: String): IData?
        }

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            //retainInstance = true

            var bundle = arguments
            var dataProvider: IDataProvider = bundle.getParcelable<Parcelable>(KEY_DATA_PROVIDER) as? IDataProvider

            // the provider is got from bundle.getParcelable
            // and would expect the `IDataRepository` reference kept 
            // in the dataProvider should be lost in the 
            // serialize/deserialize of the Parcelable
            // but it does not, and it is still working to be able to make the call and return the data from the repository

            val data: Data = dataProvider?.getDataByUUID("xxx-yyy-zzz")

            // the data is returned fine (???)
                    ......

        }

        ... ...
    }

这是 activity,它将 IDataProvider 放入 DataFragment 实例的参数中 通过 Bundle().putParcelable(KEY_DATA_PROVIDER, dataProvider)

    class DataActivity: Activity {

        var dataProvider: DataProvider? = null

        val viewModel = getViewModel()  //get the viewModel which has the dataRepository

        fun createFragment(): Fragment? {

            dataProvider = DataProvider()
            dataProvider?.let {
                dataProvider.repository = viewModel?.getDataRepository()

                val args = Bundle()
                args.putParcelable(KEY_DATA_PROVIDER, dataProvider)  //put the dataProvider in the Bundle with putParcelable

                var dataFragment = DataFragment()
                dataFragment.arguments = args  // set to its arguments
                return contentFragment
            }
            return null
        }

        override fun onDestroy() {
            super.onDestroy()

            dataProvider?.repository = null
        }


        // DataProvider implementation, 
        // it has a reference to a IDataRepository
        // but is not serialized/deserialized when it is parceling

        private var dataProvider: DataProvider? = null
        class DataProvider() : DataFragment.IDataProvider {

            var repository: IDataRepository? = null
            override fun getDataByUUID(uuid: String): IData? {
                return repository?.getData(uuid)
            }

            constructor(parcel: Parcel) : this() {}
            override fun writeToParcel(parcel: Parcel, flags: Int) {}
            override fun describeContents(): Int {
                return 0
            }

            companion object CREATOR : Parcelable.Creator<DataProvider> {
                override fun createFromParcel(parcel: Parcel): DataProvider {
                    return ContentProvider(parcel)
                }

                override fun newArray(size: Int): Array<DataProvider?> {
                    return arrayOfNulls(size)
                }
            }
        }
    }

如果按照上面的实现方式,可以预期class DataProvider() : DataFragment.IDataProvider中的成员变量repository 应该丢失,因为 writeToParcel()/readFromParcel().

中没有 serialized/deserialized 的代码

但是当 rrunning 它似乎在片段中从包中打包回来时,成员变量 repository 仍然有效。

任何人都知道为什么,或者 Parcelable 是如何serialized/deserialized?

看起来像是使用从 createFragment() 生成的片段

fun createFragment(): Fragment? {

        dataProvider = DataProvider()
        dataProvider?.let {
            dataProvider.repository = viewModel?.getDataRepository()

            val args = Bundle()
            args.putParcelable(KEY_DATA_PROVIDER, dataProvider)  //put the dataProvider in the Bundle with putParcelable

            var dataFragment = DataFragment()
            dataFragment.arguments = args  // set to its arguments
            return contentFragment
        }
        return null
    }

并做

var bundle = createFragment().arguments
var dataProvider: IDataProvider = bundle.getParcelable<Parcelable>(KEY_DATA_PROVIDER) as? IDataProvider

该捆绑包仍然具有相同的包含 parcelables 实例,因此它仍然有效。

但是在像 os 这样的情况下,杀死并恢复片段,来自新片段 arguments 的 parcelable 将有新的 parcelable 实例,并且不再有以前的引用。