Имея фрагмент, он ожидает, что IDataProvider
(который является Parcelable) будет передан через аргументы фрагмента и вместе с ним получить данные из хранилища.
это DataFragment
, который извлекает dataProvider из аргументов через bundle.getParcelable<Parcelable>(KEY_DATA_PROVIDER) as? IDataProvider
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 сериализуется / десериализуется?