有一个片段,它期望通过该片段的参数传递一个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 (???)
......
}
... ...
}
这是活动,它将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)
}
}
}
}
如果采用上述实现,则可以预期repository
中的成员变量class DataProvider() : DataFragment.IDataProvider
应该丢失,因为writeToParcel()/ readFromParcel()中没有要序列化/反序列化的代码。
但是运行时,似乎在片段中将其从包中打包回来时,成员变量repository
仍然有效。
有人知道为什么,或者如何对Parcelable进行序列化/反序列化吗?
答案 0 :(得分:0)
看起来是否使用从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
该捆绑包仍然具有包含的可包裹物品的相同实例,因此它仍然有效。
但是在像os杀死并恢复该片段的情况下,来自新片段arguments
的可打包文件将具有该可打包文件的新实例,并且将不再具有先前的引用。