BadParcelableException in Android 13

When Android 13 was introduced, I noticed in my Google Play Console that a lot of users are getting new exceptions almost daily. Mostly it were “java.lang.NoSuchFieldException” or “android.os.BadParcelableException” exceptions.

Looking at the stacktrace I had no idea what it meant:

    Exception android.os.BadParcelableException: Parcelable protocol requires a Parcelable.Creator object called CREATOR on class android.support.v7.widget.Toolbar$SavedState
    at android.os.Parcel.readParcelableCreator (Parcel.java:3367)
    at android.os.Parcel.readParcelable (Parcel.java:3272)
    at android.os.Parcel.readValue (Parcel.java:3174)
    at android.os.Parcel.readSparseArrayInternal (Parcel.java:3650)
    at android.os.Parcel.readSparseArray (Parcel.java:2792)
    at android.os.Parcel.readValue (Parcel.java:3231)
    at android.os.Parcel.readArrayMapInternal (Parcel.java:3567)
    at android.os.BaseBundle.initializeFromParcelLocked (BaseBundle.java:292)
    at android.os.BaseBundle.unparcel (BaseBundle.java:236)
    at android.os.Bundle.getSparseParcelableArray (Bundle.java:1079)
    at com.android.internal.policy.PhoneWindow.restoreHierarchyState (PhoneWindow.java:2182)
    at android.app.Activity.onRestoreInstanceState (Activity.java:1683)
    at android.app.Activity.performRestoreInstanceState (Activity.java:1636)
    at android.app.Instrumentation.callActivityOnRestoreInstanceState (Instrumentation.java:1365)
    at android.app.ActivityThread.handleStartActivity (ActivityThread.java:3596)
    at android.app.servertransaction.TransactionExecutor.performLifecycleSequence (TransactionExecutor.java:221)
    at android.app.servertransaction.TransactionExecutor.cycleToPath (TransactionExecutor.java:201)
    at android.app.servertransaction.TransactionExecutor.executeLifecycleState (TransactionExecutor.java:173)
    at android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:97)
    at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2172)
    at android.os.Handler.dispatchMessage (Handler.java:106)
    at android.os.Looper.loop (Looper.java:236)
    at android.app.ActivityThread.main (ActivityThread.java:7843)
    at java.lang.reflect.Method.invoke
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:621)
    at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:997)
    

The stacktrace looks very generic and at first I thought it had something todo with my XmlSerializer which I use to save the state of the application. For me this is one of the worst things that can happen: Getting a stacktrace with code you don’t have access to, never seen before or has the wrong line numbers.

I posted the stacktrace on Stackoverflow, where my question was closed because I didn’t provide enough debugging information. For me it was hard though to debug this problem since it only happened on some devices and only with the production release. Also my research on google and github didn’t bring me any new ideas what might be going wrong. It seems like almost no one had the same issue. I have to mention that I use Xamarin for development, but the Stacktrace looks pretty native to me. I almost gave up when after some months I thought about this error only happening in release version. Then I remembered that I use features called dexer (D8) and shrinker (R8). A dexer converts the code from byte code to dex code and a shrinker – of course shrinks it.

It then came to my mind that there is a file called “proguard.cfg” where you can configure classes that should not be removed during shrinking. Also the exception “NoSuchFieldException” indicates that classes cannot be found, so this was heading me in the right direction. After some googling I also find out that you can print to a file what the shrinker will actually remove. I opened the proguard.cfg and added the following line:

-printusage proguardprintuse.txt -keepclassmembers class * implements android.os.Parcelable { public static final ** CREATOR; }

With this I was hoping that classes will not be removed when they are used indirectly by reflection etc. After rebuilding the apk I checked the “proguardprintuse.txt” and I couldn’t find anything related to “android.os.Parcelable” anymore – which was a good sign! It means that this class will not be removed anymore.

I deployed my new apk to the google play store and could only hope that the errors will be gone. Now after several months I can definitely say that this problem has been solved foor good! I hope if you ever have this problem too, that this post will help you. I would have been happy to read about it somewhere and not spending months to figure it out.