安卓(Android):Parcelable异常

4

我在生产环境中遇到了以下异常。它与可包含类有关,但它没有显示出哪个类有问题。下面是详细的日志跟踪:

Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{in.app/in.app.activity.MainActivity}: java.lang.RuntimeException: Parcel android.os.Parcel@ae3c90f: Unmarshalling unknown type code -15962911 at offset 816
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2957)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032)
   at android.app.ActivityThread.-wrap11(Unknown Source)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
   at android.os.Handler.dispatchMessage(Handler.java:105)
   at android.os.Looper.loop(Looper.java:164)
   at android.app.ActivityThread.main(ActivityThread.java:6942)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

这发生在Activity的onStart方法中。我没有将任何Parcelable对象传递给该Activity,这是启动器之一。 如何找到指定位置的哪个Parcelable存在:
Unmarshalling unknown type code -15962911 at offset 816

此外,根据Crashlytics的数据,设备状态如下:
100%近距离
3%应用程序在后台运行
出现在多个操作系统版本中。

MainActivity

public class MainActivity extends BaseActivity implements CleanUpDelegate,
    OnFilterAppliedListener,
    UpdatePhoneNoDialog.UpdatePhoneNoListener, GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener, GenericDialogOperationListener,
    DAPopupFragment.DAPopupOperationsListener,
    OnLoginListener, HomeScreenFragmentV2.showECOOrderPopup, BottomNavigationRVAdapter.BottomNavigationItemClick

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        createBottomNavigation();
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (mGoogleApiClient != null) {
            mGoogleApiClient.connect();
        }
    }
}

由于您在生产环境中遇到了这个问题,我几乎可以确定它与ProGuard有关。由于您没有使用任何自定义的可序列化类,所以很可能是一个库的问题。您可以尝试查看您所使用的库的GitHub页面,看看是否包含了他们的ProGuard规则。 - Zun
1
发布你的主活动代码 - Vivek Mishra
@VivekMishra 主活动代码已添加。由于类非常庞大,因此我只添加了相关的方法。 - Nitish
你在onSaveInstanceState()方法中向Bundle写入了什么吗? - azizbekian
请发布您的模型(Pojo类),这是由于您的Parcelable安排。 - Atif AbbAsi
2个回答

1

由于这是在生产环境中发生的,很有可能是由于ProGuard混淆Parcelable类所致。

尝试在ProGuard配置文件中包含以下内容:

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

如需更多信息,Android 应用程序有一个推荐配置,可在 ProGuard 手册 中找到,其中详细解释了条目。


有没有办法找到未知类型代码“未知类型代码-15962911”。这主要发生在Oreo上。 - Nitish
请看这里。我不确定如何找到未知类型,但这个问题可能会帮助您复制问题并获得更多信息。 - Ayush Khare

0

错误信息:

在偏移量为XXXXX处,无法解组未知类型代码XXXXX。

当您拥有一个实现了Parcelable接口的对象且该对象格式不正确时,就会发生此错误。

public static final Parcelable.Creator<MyClass> CREATOR = new Parcelable.Creator<MyClass>(){

    @Override
    public MyClass createFromParcel(Parcel source){
        // The most common issues are in this constructor.
        return new MyClass(source);
    }

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

当你需要重新创建Parcelable对象时,将调用return new MyClass(source);(使用上面的示例)。这是最常见问题发生的地方:

  1. 您有一个特定类型的变量,并且您正在将其解组为另一种类型。

例如:您有一个变量id,它是长整型,您正在像这样读取它id = source.readInt();

  1. 您正在尝试读取在您的Parcelable中不可用的值。

例如:您尝试id = source.readInt();但您忘记了dest.writeInt(id);

  1. 您的Parcelable扩展自另一个也是Parcelable的对象,并且您忘记在读写方法中调用super。

例如:

@Override
public void writeToParcel(Parcel dest, int flags) {
    // This is missing
    super.writeToParcel(dest, flags);
}
  • 缺少Proguard规则:
  • 这将保留所有Parcelable实现的特殊字段:

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

    简短概述 如果没有所有源代码,很难找出问题所在。 我的建议是您检查您在活动中使用的所有Parcelable对象,并检查它们是否格式正确。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接