Closed russellbanks closed 3 years ago
Can you show me the exception that is thrown? Does this happen with every type of sheet in the sample? (for dialog and bottom-sheet?)
I have done some testing on the sample app. It occurs regardless of dialog or bottom sheet but only seems to happen with specific use cases within the sample app. For example, it can work in some InfoSheets but not in others. It crashes all sheets in my app.
In the sample app,
This is the exception I get when it occurs in my app:
Process: org.bandev.buddhaquotes, PID: 10722
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = org.bandev.buddhaquotes.fragments.QuoteFragment$onViewCreated$3$1$1)
at android.os.Parcel.writeSerializable(Parcel.java:1833)
at android.os.Parcel.writeValue(Parcel.java:1780)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:928)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1589)
at android.os.Bundle.writeToParcel(Bundle.java:1253)
at android.os.Parcel.writeBundle(Parcel.java:997)
at androidx.fragment.app.FragmentState.writeToParcel(FragmentState.java:127)
at android.os.Parcel.writeTypedObject(Parcel.java:1634)
at android.os.Parcel.writeTypedList(Parcel.java:1513)
at android.os.Parcel.writeTypedList(Parcel.java:1470)
at androidx.fragment.app.FragmentManagerState.writeToParcel(FragmentManagerState.java:58)
at android.os.Parcel.writeParcelable(Parcel.java:1801)
at android.os.Parcel.writeValue(Parcel.java:1707)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:928)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1589)
at android.os.Bundle.writeToParcel(Bundle.java:1253)
at android.os.Parcel.writeBundle(Parcel.java:997)
at android.os.Parcel.writeValue(Parcel.java:1698)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:928)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1589)
at android.os.Bundle.writeToParcel(Bundle.java:1253)
at android.os.Parcel.writeBundle(Parcel.java:997)
at android.os.Parcel.writeValue(Parcel.java:1698)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:928)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1589)
at android.os.Bundle.writeToParcel(Bundle.java:1253)
at android.app.IActivityTaskManager$Stub$Proxy.activityStopped(IActivityTaskManager.java:4545)
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:214)
at android.app.ActivityThread.main(ActivityThread.java:7682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Caused by: java.io.NotSerializableException: com.maxkeppeler.sheets.options.OptionsSheet
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:1828)
at android.os.Parcel.writeValue(Parcel.java:1780)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:928)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1589)
at android.os.Bundle.writeToParcel(Bundle.java:1253)
at android.os.Parcel.writeBundle(Parcel.java:997)
at androidx.fragment.app.FragmentState.writeToParcel(FragmentState.java:127)
at android.os.Parcel.writeTypedObject(Parcel.java:1634)
at android.os.Parcel.writeTypedList(Parcel.java:1513)
at android.os.Parcel.writeTypedList(Parcel.java:1470)
at androidx.fragment.app.FragmentManagerState.writeToParcel(FragmentManagerState.java:58)
at android.os.Parcel.writeParcelable(Parcel.java:1801)
at android.os.Parcel.writeValue(Parcel.java:1707)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:928)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1589)
at android.os.Bundle.writeToParcel(Bundle.java:1253)
at android.os.Parcel.writeBundle(Parcel.java:997)
at android.os.Parcel.writeValue(Parcel.java:1698)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:928)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1589)
at android.os.Bundle.writeToParcel(Bundle.java:1253)
at android.os.Parcel.writeBundle(Parcel.java:997)
at android.os.Parcel.writeValue(Parcel.java:1698)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:928)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1589)
at android.os.Bundle.writeToParcel(Bundle.java:1253)
at android.app.IActivityTaskManager$Stub$Proxy.activityStopped(IActivityTaskManager.java:4545)
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:214)
at android.app.ActivityThread.main(ActivityThread.java:7682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)```
I couldn't figure out why it wants to serialize the class OptionsSheet (or another) in the first place - and for what reason only specific configurations or sheet types lead to this Exception, while other keep working. Thanks a lot for this issue. If you have any idea, just let me know. When I have some more free time, I will look into this.
I don't know how the mechanism of lambda serialization works in kotlin, but the problem is serializable listeners on saveInstanceState. Android trying to serialize MainActivity and that's reason why app crashes:
After comment all lines with listeners and icons buttons - all works fine (activity is not destroyed when we go app switcher).
Of course if Activity is destroyed all listeners were gone. (you can simulate that by use split screen).
That's interesting. I assume the working examples in the sample just didn't make use of a lambda listener then.
Seems like I have to create wrapper classes that are parcalabe / serializable and pass the lambda functions before adding them to the Bundle. On the other hand I could just replace them with (functional) interfaces that are parcalabe / serializable, which would save me some additional classes.
I tend to decide for the latter. What do you think?
(Using lambda functions seemed so convenient previously...)
I tried creating classes for listeners with serializable interfaces and it doesn't work (same error). It still have reference to MainActivity which cannot be serialized. I research some articles about serialization of listeners and people re-registering listeners. I use Material Dialogs(https://github.com/afollestad/material-dialogs) library in my other project and this library doesn't restore sheets after onPause(). Maybe this constraint is the reason why.
I found this description about listener serialization:
The listener variable is a reference to an object instance reference: https://stackoverflow.com/a/36036818
I think sheets should be recreating by app not library.
That's all I could find as well. It makes sense that listeners are not serializable. However, from a convenience standpoint it certainly would be nice if a dialog or bottom-sheet could recover from a configuration change. :)
I agree with you - I will be removing the auto-restoration of the sheets.
Describe the bug If you swipe the app into the app switcher while a sheet is open, when you return to it, the app will crash.
Library Version: 2.1.3
To Reproduce Steps to reproduce the behavior:
Expected behavior The user should be able to return to the app without it crashing and the sheet remain as it was.
Additional context This also occurs in the sheets sample app.
Screenshots I have attached a video of this happening in my app.
https://user-images.githubusercontent.com/74878137/110211291-e442be80-7e8d-11eb-9483-54ae8115a591.mp4