如何在 Android 中的偏移量 YYY 处修复解组未知类型代码 XXX?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21844945/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:11:07  来源:igfitidea点击:

How to fix Unmarshalling unknown type code XXX at offset YYY in Android?

androidserializationmarshallingunmarshallingparcelable

提问by 4ntoine

I'm having app crash on resume because of Unmarshalling exception. I've checked all the Serializables have constructor with no parameters and even checked all the serializables using ObjectStream (save to file and load from file). How can i understand actual class type for parcelable offset that cause exception:

由于解组异常,我在恢复时遇到应用程序崩溃。我已经检查了所有 Serializable 具有没有参数的构造函数,甚至使用 ObjectStream 检查了所有可序列化(保存到文件并从文件加载)。我如何理解导致异常的可分割偏移的实际类类型:

Parcel android.os.Parcel@42209460: Unmarshalling unknown type code
 2131165303 at offset 3748
         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2080)
         at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2105)
         at android.app.ActivityThread.access0(ActivityThread.java:136)
         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1201)
         at android.os.Handler.dispatchMessage(Handler.java:99)
         at android.os.Looper.loop(Looper.java:137)
         at android.app.ActivityThread.main(ActivityThread.java:4876)
         at java.lang.reflect.Method.invokeNative(Native Method)
         at java.lang.reflect.Method.invoke(Method.java:511)
         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:804)
         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:571)
         at com.kdgdev.xtension.core.XtensionMain.main(XtensionMain.java:91)
         at dalvik.system.NativeStart.main(Native Method)
        Caused by: java.lang.RuntimeException: Parcel android.os.Parcel@42209460: Unmarshalling unknown type code 2131165303
 at offset 3748
         at android.os.Parcel.readValue(Parcel.java:2032)
         at android.os.Parcel.readSparseArrayInternal(Parcel.java:2255)
         at android.os.Parcel.readSparseArray(Parcel.java:1687)
         at android.os.Parcel.readValue(Parcel.java:2022)
         at android.os.Parcel.readMapInternal(Parcel.java:2226)
         at android.os.Bundle.unparcel(Bundle.java:223)
         at android.os.Bundle.getSparseParcelableArray(Bundle.java:1232)
        at com.android.internal.policy.impl.PhoneWindow.restoreHierarchyState(PhoneWindow.java:1690)
         at android.app.Activity.onRestoreInstanceState(Activity.java:999)
         at com.actionbarsherlock.app.SherlockFragmentActivity.onRestoreInstanceState(Unknown
 Source)
         at name.myname.android.app.ui.MainActivity.onRestoreInstanceState(Unknown
 Source)
         at android.app.Activity.performRestoreInstanceState(Activity.java:971)
         at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1130)
         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2058)
       ... 12 more

Saved data consists of Bundles and Serializables and all of them look good.

保存的数据由Bundles 和Serializables组成,它们看起来都不错。

I'm going to do the next:

我接下来要做的是:

try {
// unmarshalling
} catch (Throwable t) {
// look offset 
}

How can i understand what type is actually for Parcelable offset?

我如何理解 Parcelable 偏移量的实际类型?

采纳答案by 4ntoine

It's because of Proguard obfuscation - it processed Parcelable. solution: Proguard causing RuntimeException (Unmarshalling unknown type code) in Parcelable class

这是因为 Proguard 混淆 - 它处理了 Parcelable。解决方案:Proguard 在 Parcelable 类中导致 RuntimeException (Unmarshalling unknown type code)

回答by asozcan

There's some rules for write and read parcelables.

写入和读取 Parcelable 有一些规则。

1- Be careful about type mismatch. If you write int, don't try to read long etc.

1- 注意类型不匹配。如果你写 int,不要试图读 long 等。

2- Be careful about order of writes and reads. Objects must be at the same sort order when reading and writing.

2- 注意写入和读取的顺序。对象在读取和写入时必须处于相同的排序顺序。

Both of these can cause "Unmarshalling unknown type code".

这两者都可能导致“解组未知类型代码”。

回答by Subhas P

If a type of List is added, it should be:

如果添加了一个List类型,应该是:

@Override
    public void writeToParcel(Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        dest.writeList(this.mList);

and unparcel it using the class type like this:

并使用这样的类类型解包它:

protected MyClass(Parcel in) {
        super(in);
        this.mList = new ArrayList<>();
        in.readList(this.mList, MyRequiredClass.class.getClassLoader());

回答by Ignacio Tomas Crespo

In my case it is fixed after upgrading support library to 23.2.1

在我的情况下,它是在将支持库升级到 23.2.1 后修复的

回答by Roshan

Just remove all parcelable methods and generate them again with valid sequence

只需删除所有可分割的方法并使用有效序列再次生成它们

回答by Divy Sourabh

It's not Proguard related issue.. But when proguard and minify enable it's issue occurrence is always.

这不是 Proguard 相关的问题。但是当 proguard 和 minify 启用时,它的问题总是发生。

Problem is in sequence of writing and reading of object...sequence should be same, as it is like reading file.

问题在于对象的写入和读取顺序......顺序应该相同,因为它就像读取文件一样。

You can use android studio plug in for make class as parcelable https://plugins.jetbrains.com/plugin/7332?pr=

您可以使用 android studio 插件作为可打包的类https://plugins.jetbrains.com/plugin/7332?pr=

回答by hovo888s

In my case my class don't added CREATOR filed when extending from another Parcelable parent.

在我的情况下,当从另一个 Parcelable 父级扩展时,我的班级没有添加 CREATOR 归档。

public class Image implements Parcelable {
        protected Image(Parcel in) {
        }

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

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

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
        }
}

public class ImageChild extends Image {
        protected ImageChild(Parcel in) {
            super(in);
        }


        @Override
        public int describeContents() {
            return 0;
        }

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

In ImageChild missing CREATOR field

在 ImageChild 中缺少 CREATOR 字段

回答by Ronaldo Albertini

Using Kotlin, the object 'Nota' has a Custom object 'CentroCusto' that contains only primitive properties.

使用 Kotlin,对象“Nota”有一个只包含原始属性的自定义对象“CentroCusto”。

class Nota(var id: Int? = null, var centroCusto: ArrayList<CentroCusto>? = null) : Parcelable {

constructor(source: Parcel) : this(
        source.readValue(Int::class.java.classLoader) as Int?,
        //Exception in below line -> Unmarshalling unknown type code 
        source.createTypedArrayList(CentroCusto.CREATOR) 
)

override fun describeContents() = 0

override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
    writeValue(id)
    writeTypedList(centroCusto)
}

companion object {
    @JvmField
    val CREATOR: Parcelable.Creator<Nota> = object : Parcelable.Creator<Nota> {
        override fun createFromParcel(source: Parcel): Nota = Nota(source)
        override fun newArray(size: Int): Array<Nota?> = arrayOfNulls(size)
    }
}

The CentroCusto class:

CentroCusto 类:

class CentroCusto(var id: Int? = null, var descricao: String? = null, var aprovacaoDiretoria: Int? = null, var permiteMarcar: Boolean? = null) : Parcelable {

constructor(parcel: Parcel) : this(
        parcel.readValue(Int::class.java.classLoader) as? Int,
        parcel.readString(),
        parcel.readValue(Int::class.java.classLoader) as? Int,
        parcel.readValue(Boolean::class.java.classLoader) as? Boolean) {
}

override fun writeToParcel(parcel: Parcel, flags: Int) {
    parcel.writeValue(id)
    parcel.writeString(descricao)
    parcel.writeValue(aprovacaoDiretoria)
    parcel.writeValue(permiteMarcar)
}

override fun describeContents(): Int {
    return 0
}

companion object CREATOR : Parcelable.Creator<CentroCusto> {
    override fun createFromParcel(parcel: Parcel): CentroCusto {
        return CentroCusto(parcel)
    }

    override fun newArray(size: Int): Array<CentroCusto?> {
        return arrayOfNulls(size)
    }
}

}

回答by Roman Minenok

In my case it was caused by data size exceeding max limit of that can be put to Parcel which is about 1 MB.

在我的情况下,这是由于数据大小超过可以放入大约 1 MB 的 Parcel 的最大限制造成的。

Solution: optimize your Parcelable code to put as less data as possible (e.g. do not put Serializable objects to Parcel)

解决方案:优化您的 Parcelable 代码以尽可能减少数据(例如不要将 Serializable 对象放入 Parcel)

回答by Richard R

Just to add: this error can also happen, when using custom views and don't properly save/restore their states via onSaveInstanceState()and onRestoreInstanceState().

补充一点:当使用自定义视图并且没有通过onSaveInstanceState()和正确保存/恢复它们的状态时,也会发生这个错误onRestoreInstanceState()

So if this error occurs, also check your custom views.

因此,如果发生此错误,还要检查您的自定义视图。