Proguard的在Parcelable类引起的RuntimeException(解组未知类型code) [英] Proguard causing RuntimeException (Unmarshalling unknown type code) in Parcelable class

查看:263
本文介绍了Proguard的在Parcelable类引起的RuntimeException(解组未知类型code)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我,如果我离开我的应用程序,并在一段时间后打开它得到这个例外。我的主要活动包括三个不同的片段一ViewPager的。我也做了一些东西,在应用类,我不认为涉及到这个问题。

这是个例外:

  

的RuntimeException(@Parcel:readValue:2065){无法启动活动   ComponentInfo {com.emu / com.emu.ActivityMain}:   java.lang.RuntimeException的:包裹android.os.Parcel@419526d0:   解组未知类型code 2131361816偏移量332}

我看到很多这样的例外发生在谷歌分析用户的手机。所有这些都只是readValue后数和十六进制数相同的后@这是2065和419526d0在上面的异常。

该异常不点的code任意行。我搜索关于这一点,现在看来,这涉及到错误的书面包裹。虽然我没有任何包裹在我MainActivity。我不知道什么可能会导致此。

---编辑------------------------------------------- -----------------------------

我转载的例外。它发生时,应用程序是用阔叶主页按钮,并从内存中清除得到了打开某些其他消耗内存的应用程序后。当再次启动异常情况发生。到现在我在想,关闭应用程序,从近期的任务或DDMS有同样的效果,但显然事实并非如此。

@EricWoodruf帮助我发现包裹是在某个地方进口的图书馆。我发现包裹在PagerSlidingTabStrip这是我从网上下载了。这是包裹相关的code,但我真的不知道什么是错在这里:

 公共类PagerSlidingTabStrip扩展Horizo​​ntalScrollView
{
    @覆盖
    公共无效onRestoreInstanceState(Parcelable州)
    {
        SavedState savedState =(SavedState)状态;
        super.onRestoreInstanceState(savedState.getSuperState());
        currentPosition = savedState.currentPosition;
        requestLayout();
    }

    @覆盖
    公共Parcelable的onSaveInstanceState()
    {
        Parcelable超级大国= super.onSaveInstanceState();
        SavedState savedState =新SavedState(覆);
        savedState.currentPosition = currentPosition;
        返回savedState;
    }

    静态类SavedState扩展BaseSavedState
    {
        INT currentPosition;

        公共SavedState(Parcelable超级大国)
        {
            超(超国家);
        }

        私人SavedState(包裹中)
        {
            超级(在);
            currentPosition = in.readInt();
        }

        @覆盖
        公共无效writeToParcel(包裹包裹,诠释标志)
        {
            super.writeToParcel(包裹,旗);
            parcel.writeInt(currentPosition);
        }

        公共静态最终Parcelable.Creator< SavedState> CREATOR =新Parcelable.Creator< SavedState>()
        {
            @覆盖
            公共SavedState createFromParcel(包裹中)
            {
                返回新SavedState(中);
            }

            @覆盖
            公共SavedState [] newArray(INT尺寸)
            {
                返回新SavedState【尺寸】;
            }
        };
    }
}
 

----编辑2 ----------------------------------------- ------------------------

在我能复制我发现了这个问题,出现这种情况只有在它是由我的密钥签名和proguarded神器!调试一不具有的问题!

在神器的我残疾ProGuard,并将它的工作原理就像没有例外魅力。但是,什么样的ProGuard做,导致这个问题?

我尝试添加这ProGuard的,但没有工作:

  -keep类toolfa.android.base.ui.PagerSlidingTabStrip {*; }
-dontwarn toolfa.android.base.ui.PagerSlidingTabStrip
 

这是我目前的ProGuard配置:

  -keep类com.nineoldandroids ** {*。 }
-dontwarn com.nineoldandroids。**

-keep类ir.adad ** {*。 }
-dontwarn ir.adad。**

-keep类android.support.v4 ** {*。 }
-dontwarn android.support.v4。**

-keep类toolfa.android.base.ui.PagerSlidingTabStrip {*; }
-dontwarn toolfa.android.base.ui.PagerSlidingTabStrip

-keep类toolfa.android.sega.ActivityEmulator {*; }
-keep类toolfa.android.sega.Zip {*; }
 

解决方案

当我们发现在评论,这个例外是一系列的 ProGuard的混淆Parcelable类。解决方法是将这一片段ProGuard的配置文件中:

  -keepclassmembers类*实现android.os.Parcelable {
    静态** CREATOR;
}
 

我想具体的问题在这里是ProGuard的混淆了 CREATOR PagerSlidingTabStrip 的成员,但由于 SavedState 是<一个子类href="http://developer.android.com/reference/android/view/View.BaseSavedState.html"><$c$c>View.BaseSavedState,超类成员仍然可用(这就是为什么它没有抛出一个<一个href="http://developer.android.com/reference/android/os/BadParcelableException.html"><$c$c>BadParcelableException),但使用不同的数据结构,并没有写自定义属性到包裹输出。

有一个在 ProGuard的手册(请参阅例子/一个完整的Andr​​oid应用程序)建议的配置,有关条目详细的说明。例如,它包含了你应该保持在清单或其他XML文件中使用的所有类名。

I get this exception if I leave my app and open it after some time. My main activity consist of a ViewPager with three different fragments. I also do some stuff in Application class which I don't think relates to the problem.

This is the exception:

RuntimeException (@Parcel:readValue:2065) {Unable to start activity ComponentInfo{com.emu/com.emu.ActivityMain}: java.lang.RuntimeException: Parcel android.os.Parcel@419526d0: Unmarshalling unknown type code 2131361816 at offset 332}

I see lots of this exception happening on users phones in google analytics. All of them are the same except number after readValue and hex number after @ which are 2065 and 419526d0 in above exception.

The exception doesn't point any line of code. I searched about this and it seems it relates to wrong writing to parcel. Although I don't have any parcel in my MainActivity. I don't know what may cause this.

--- EDIT ------------------------------------------------------------------------

I reproduced the exception. It happens when App is leaved with home button, and got cleared from memory after opening some other memory consuming app. When starting it again exception happens. Till now I was thinking that closing app from recent task or from DDMS have the same effect but apparently it doesn't.

@EricWoodruf helped me to find that parcel is somewhere in imported library. I find the parcel in PagerSlidingTabStrip which I had downloaded from web. This is the parcel related code, but I don't really know what is wrong here:

public class PagerSlidingTabStrip extends HorizontalScrollView
{
    @Override
    public void onRestoreInstanceState(Parcelable state)
    {
        SavedState savedState = (SavedState) state;
        super.onRestoreInstanceState(savedState.getSuperState());
        currentPosition = savedState.currentPosition;
        requestLayout();
    }

    @Override
    public Parcelable onSaveInstanceState()
    {
        Parcelable superState = super.onSaveInstanceState();
        SavedState savedState = new SavedState(superState);
        savedState.currentPosition = currentPosition;
        return savedState;
    }

    static class SavedState extends BaseSavedState
    {
        int currentPosition;

        public SavedState(Parcelable superState)
        {
            super(superState);
        }

        private SavedState(Parcel in)
        {
            super(in);
            currentPosition = in.readInt();
        }

        @Override
        public void writeToParcel(Parcel parcel, int flags)
        {
            super.writeToParcel(parcel, flags);
            parcel.writeInt(currentPosition);
        }

        public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>()
        {
            @Override
            public SavedState createFromParcel(Parcel in)
            {
                return new SavedState(in);
            }

            @Override
            public SavedState[] newArray(int size)
            {
                return new SavedState[size];
            }
        };
    }
}

---- EDIT 2 -----------------------------------------------------------------

After I could reproduce the problem I found out that this happens only in Artifact which is signed by my key and proguarded! The debug one doesn't have the problem!

I disabled proguard on artifact and it works like a charm without the exception. But, what proguard do that result in this problem?

I tried adding this to proguard but didn't work:

-keep class toolfa.android.base.ui.PagerSlidingTabStrip { *; }
-dontwarn toolfa.android.base.ui.PagerSlidingTabStrip

this is my current proguard config:

-keep class com.nineoldandroids.** { *; }
-dontwarn com.nineoldandroids.**

-keep class ir.adad.** { *; }
-dontwarn ir.adad.**

-keep class android.support.v4.** { *; }
-dontwarn android.support.v4.**

-keep class toolfa.android.base.ui.PagerSlidingTabStrip { *; }
-dontwarn toolfa.android.base.ui.PagerSlidingTabStrip

-keep class toolfa.android.sega.ActivityEmulator { *; }
-keep class toolfa.android.sega.Zip { *; }

解决方案

As we found out in the comments, the exception was the result of ProGuard obfuscating Parcelable classes. The fix is to include this snippet in the ProGuard configuration file:

-keepclassmembers class * implements android.os.Parcelable {
    static ** CREATOR;
}

I guess the specific problem here was that ProGuard obfuscated the CREATOR member of PagerSlidingTabStrip, but since SavedState is a subclass of View.BaseSavedState, the superclass member was still available (this is why it didn't throw a BadParcelableException), but that uses a different data structure and didn't write the custom attributes into the Parcel output.

There is a recommended configuration available in the ProGuard Manual (see Examples / A complete Android application), with detailed explanation about entries. For example, it includes that you should keep all class names used in the manifest or other XML files.

这篇关于Proguard的在Parcelable类引起的RuntimeException(解组未知类型code)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆