Putting my app on the background or changing into another app, makes my app crash in the background with the error
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com...MyFragment).
...
Caused by: java.io.NotSerializableException: androidx.lifecycle.ViewModelLazy
The part of the code which happens is a viewModel on my fragment
private val mPlayVM: PlayViewModel by viewModels()
The solution I'm used to is putting the @Transient tag, but it doesn't accept ("This annotation is not applicable to target member property with delegate"). Another solution was making my classes to implement Serializable, but none actually worked.
This is the beggining of my PlayViewModel class
@HiltViewModel
class PlayViewModel @Inject constructor() : PlayViewModel(), Serializable {
...
}
Why does it crash because of Serializable on a ViewModel?
Full stack trace
2022-05-30 19:21:45.481 17378-17378/com.myproj E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.myproj, PID: 17378
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com...MyFragment)
at android.os.Parcel.writeSerializable(Parcel.java:2125)
at android.os.Parcel.writeValue(Parcel.java:1895)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:987)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1303)
at android.os.Parcel.writeBundle(Parcel.java:1056)
at androidx.fragment.app.FragmentState.writeToParcel(FragmentState.java:159)
at android.os.Parcel.writeTypedObject(Parcel.java:1749)
at android.os.Parcel.writeTypedList(Parcel.java:1628)
at android.os.Parcel.writeTypedList(Parcel.java:1585)
at androidx.fragment.app.FragmentManagerState.writeToParcel(FragmentManagerState.java:64)
at android.os.Parcel.writeParcelable(Parcel.java:1916)
at android.os.Parcel.writeValue(Parcel.java:1822)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:987)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1303)
at android.os.Parcel.writeBundle(Parcel.java:1056)
at androidx.fragment.app.FragmentState.writeToParcel(FragmentState.java:161)
at android.os.Parcel.writeTypedObject(Parcel.java:1749)
at android.os.Parcel.writeTypedList(Parcel.java:1628)
at android.os.Parcel.writeTypedList(Parcel.java:1585)
at androidx.fragment.app.FragmentManagerState.writeToParcel(FragmentManagerState.java:64)
at android.os.Parcel.writeParcelable(Parcel.java:1916)
at android.os.Parcel.writeValue(Parcel.java:1822)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:987)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1303)
at android.os.Parcel.writeBundle(Parcel.java:1056)
at android.os.Parcel.writeValue(Parcel.java:1813)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:987)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1303)
at android.os.Parcel.writeBundle(Parcel.java:1056)
at android.os.Parcel.writeValue(Parcel.java:1813)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:987)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1303)
at android.app.IActivityTaskManager$Stub$Proxy.activityStopped(IActivityTaskManager.java:4969)
at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:145)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8645)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Caused by: java.io.NotSerializableException: androidx.lifecycle.ViewModelLazy
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1240)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1604)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1565)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1488)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1234)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:354)
at android.os.Parcel.writeSerializable(Parcel.java:2120)
at android.os.Parcel.writeValue(Parcel.java:1895)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:987)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1303)
at android.os.Parcel.writeBundle(Parcel.java:1056)
at androidx.fragment.app.FragmentState.writeToParcel(FragmentState.java:159)
at android.os.Parcel.writeTypedObject(Parcel.java:1749)
at android.os.Parcel.writeTypedList(Parcel.java:1628)
at android.os.Parcel.writeTypedList(Parcel.java:1585)
at androidx.fragment.app.FragmentManagerState.writeToParcel(FragmentManagerState.java:64)
at android.os.Parcel.writeParcelable(Parcel.java:1916)
at android.os.Parcel.writeValue(Parcel.java:1822)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:987)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1303)
at android.os.Parcel.writeBundle(Parcel.java:1056)
at androidx.fragment.app.FragmentState.writeToParcel(FragmentState.java:161)
at android.os.Parcel.writeTypedObject(Parcel.java:1749)
at android.os.Parcel.writeTypedList(Parcel.java:1628)
at android.os.Parcel.writeTypedList(Parcel.java:1585)
at androidx.fragment.app.FragmentManagerState.writeToParcel(FragmentManagerState.java:64)
at android.os.Parcel.writeParcelable(Parcel.java:1916)
at android.os.Parcel.writeValue(Parcel.java:1822)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:987)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1303)
at android.os.Parcel.writeBundle(Parcel.java:1056)
at android.os.Parcel.writeValue(Parcel.java:1813)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:987)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1303)
at android.os.Parcel.writeBundle(Parcel.java:1056)
at android.os.Parcel.writeValue(Parcel.java:1813)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:987)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1620)
at android.os.Bundle.writeToParcel(Bundle.java:1303)
at android.app.IActivityTaskManager$Stub$Proxy.activityStopped(IActivityTaskManager.java:4969)
at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:145)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8645)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
Edit: some more code for clarifications
There is an Adapter for the ViewPager
class AdapterVPGens(
fragment: Fragment,
private val mGenList: MutableList<Generator>,
private val mIAdventurePlay: IAdventurePlay,
private val mAdvList: MutableList<AdvList>
) : FragmentStateAdapter(fragment) {
override fun createFragment(position: Int): Fragment {
return FragmentGenInstance.newInstance(
mGenList[position],
mIAdventurePlay,
mAdvList[position])
}
override fun getItemCount(): Int = mGenList.size
}
For which is created on my initial fragment and passed into my vp
val adapterVPGens = AdapterVPGenerators(this, mGensList, this, advList)
binding.viewPagerGens.adapter = adapterVPGens
The third argument is an interface IAdventurePlay which the initial fragment implements, that's why the this on constructor. The IAdventurePlay has just some basic functions for the viewPager fragments to call. The initial fragment has different objects like the viewModel, some organizers/managers/etc, but none are passed into the adapter, only the current fragment and some lists of objects. The functions inherited from the interface, they do have some implementations using different objects, but again, none are passed into the adapter or any bundle (at least not intended)
Just to clarify, even though the initial fragment is "passed as an argument", only the interface inheritance is used. The viewPager fragments can't call any objects from the initial fragment