0
votes

Recently, we have been getting a few of following exceptions in our app:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp.android/com.myapp.android.WelcomeActivity}: java.lang.RuntimeException: Parcel android.os.Parcel@426f0118: Unmarshalling unknown type code 2131558952 at offset 736 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2429) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2493) at android.app.ActivityThread.access$800(ActivityThread.java:166) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1283) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5584) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.RuntimeException: Parcel android.os.Parcel@426f0118: Unmarshalling unknown type code 2131558952 at offset 736 at android.os.Parcel.readValue(Parcel.java:2087) at android.os.Parcel.readSparseArrayInternal(Parcel.java:2382) at android.os.Parcel.readSparseArray(Parcel.java:1742) at android.os.Parcel.readValue(Parcel.java:2077) at android.os.Parcel.readArrayMapInternal(Parcel.java:2321) at android.os.Bundle.unparcel(Bundle.java:249) at android.os.Bundle.getSparseParcelableArray(Bundle.java:1273) at com.android.internal.policy.impl.PhoneWindow.restoreHierarchyState(PhoneWindow.java:1884) at android.app.Activity.onRestoreInstanceState(Activity.java:989) at android.app.Activity.performRestoreInstanceState(Activity.java:961) at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1145)

at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2407) ... 11 more

I checked my activity but there is nothing related to Parcelable stuff. So I dug more and found Parcelable code in one of our widgets that is being used in the activity. I have very high suspicion that it might be caused by the following code:

protected override void OnRestoreInstanceState(IParcelable state)
        {
            try
            {
                SavedState savedState = (SavedState)state;
                base.OnRestoreInstanceState(savedState.SuperState);
                mCurrentPage = savedState.CurrentPage;
                mSnapPage = savedState.CurrentPage;
            }
            catch
            {
                base.OnRestoreInstanceState(state);
                // Ignore, this needs to support IParcelable...
            }
            RequestLayout();
        }

        protected override IParcelable OnSaveInstanceState()
        {
            var superState = base.OnSaveInstanceState();
            var savedState = new SavedState(superState)
            {
                CurrentPage = mCurrentPage
            };
            return savedState;
        }

        private class SavedState : BaseSavedState
        {
            public int CurrentPage { get; set; }

            public SavedState(IParcelable superState) : base(superState)
            {
            }

            private SavedState(Parcel parcel) : base(parcel)
            {
                CurrentPage = parcel.ReadInt();
            }

            public override void WriteToParcel(Parcel dest, ParcelableWriteFlags flags)
            {
                base.WriteToParcel(dest, flags);
                dest.WriteInt(CurrentPage);
            }

            [ExportField("CREATOR")]
            private static SavedStateCreator InitializeCreator()
            {
                return new SavedStateCreator();
            }

            private class SavedStateCreator : Java.Lang.Object, IParcelableCreator
            {
                public Java.Lang.Object CreateFromParcel(Parcel source)
                {
                    return new SavedState(source);
                }

                public Java.Lang.Object[] NewArray(int size)
                {
                    return new Object[size];
                }
            }
        }

The code was actually taken from this example in here: https://github.com/xamarin/monodroid-samples/blob/master/ViewPagerIndicator/ViewPagerIndicator/Library/CirclePageIndicator.cs

I have been personally unable to reproduce this but it has come out in crash reporting for our app.

Any tips on this would be appreciated.

1

1 Answers

0
votes

Fixed by removing all the creator stuff and sticking with the basics:

protected override void OnRestoreInstanceState(IParcelable state)
        {
            var bundle = state as Bundle;
            if (bundle != null)
            {
                mCurrentPage = bundle.GetInt("currentPage", 0);
                mSnapPage = mCurrentPage;
                state = (IParcelable)bundle.GetParcelable("superState");
            }
            base.OnRestoreInstanceState(state);
            RequestLayout();
        }

        protected override IParcelable OnSaveInstanceState()
        {
            var bundle = new Bundle();
            bundle.PutParcelable("superState", base.OnSaveInstanceState());
            bundle.PutInt("currentPage", mCurrentPage);
            return bundle;
        }