Proguard在Parcelable类中导致RuntimeException(Unmarshalling unknown type code)
如果我离开我的应用程序并在一段时间后打开它,我会得到这个exception。 我的主要活动包括一个ViewPager与三个不同的片段。 我也在Application类中做了一些我不认为与问题有关的东西。
这是例外:
RuntimeException(@Parcel:readValue:2065){无法启动活动ComponentInfo {com.emu / com.emu.ActivityMain}:java.lang.RuntimeException:Parcel android.os.Parcel@419526d0:Unmarshalling未知types代码2131361816在偏移量332 }
我在谷歌分析中看到用户手机上发生了这种exception。 除了上述例外情况下的2065和419526d0之后的readValue和后面的hex数字,它们都是相同的。
例外不指出任何代码行。 我search了这个,似乎涉及到写错包裹。 虽然我的MainActivity中没有任何包裹。 我不知道是什么原因造成的。
—编辑———————————————- ————————–
我重现了这个例外。 它发生在应用程序离开主页button,并打开一些其他内存消耗应用程序后从内存中清除。 当再次启动时发生exception。 到目前为止,我正在考虑从最近的任务或从DDMSclosures应用程序具有相同的效果,但显然它没有。
@EricWoodruf帮我find了包裹在import图书馆的某处。 我从网上下载的PagerSlidingTabStrip中find了这个包裹。 这是与包裹有关的代码,但是我不知道这里有什么错误:
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]; } }; } }
—-编辑2 ——————————————– ———————
在我能重现这个问题之后,我发现这只发生在由我的密钥签名并被编程的工件中! debugging的人没有问题!
我在神器上禁用了proguard,它像一个魅力没有例外的作品。 但是,什么proguard导致这个问题呢?
我试图添加到proguard,但没有工作:
-keep class toolfa.android.base.ui.PagerSlidingTabStrip { *; } -dontwarn toolfa.android.base.ui.PagerSlidingTabStrip
这是我目前的proguardconfiguration:
-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 { *; }
正如我们在评论中发现的那样, ProGuard混淆了Parcelable类的结果是个例外。 解决方法是将这个片段包含在ProGuardconfiguration文件中:
-keepclassmembers class * implements android.os.Parcelable { static ** CREATOR; }
我猜这里的具体问题是ProGuard混淆了PagerSlidingTabStrip
的CREATOR
成员,但由于SavedState
是SavedState
的子类,超类成员仍然可用(这就是为什么它没有抛出BadParcelableException
),但是使用不同的数据结构,并没有将自定义属性写入Parcel
输出。
ProGuard手册中提供了适用于Android应用程序的推荐configuration,并提供有关条目的详细说明。 例如,它包括您应该保留在清单或其他XML文件中使用的所有类名称。
我想我知道这是为什么发生。 我不确定,所以我可能是错的。
所以,就我而言,我也在我的应用程序中使用viewpager来显示一些数据库数据(使用游标)。 现在,如果我在后台离开应用程序,并在很长一段时间(几个小时)后恢复,Android决定杀死我的应用程序。 在恢复应用程序,它重build我的活动。 但是,我的适配器中的基础数据集不会被恢复。
要解决这个问题,我正在查询onResume()
数据如果getCount()
返回0。
在你身边,我认为你的应用也一样。 尝试把你的onResume的日志,看看是否是这种情况?