Как исправить Unmarshalling неизвестный код типа XXX при смещении YYY в Android?

У меня сбой приложения на резюме из-за исключения Unmarshalling. Я проверил, что у всех Serializables есть конструктор без параметров и даже проверял все сериализаторы с помощью ObjectStream (сохранение в файл и загрузка из файла). Как я могу понять фактический тип класса для разумного смещения, вызывающего исключение:

Parcel [email protected]: 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.access$600(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 [email protected]: 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

Сохраненные данные состоят из Bundle и Serializable и все они выглядят хорошо.

Я собираюсь сделать следующее:

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

Как я могу понять, какой тип на самом деле подходит для Parcelable offset?

Ответ 2

Там есть некоторые правила для написания и чтения посылок.

1- Будьте осторожны с несоответствием типов. Если вы пишете int, не пытайтесь читать долго и т.д.

2- Соблюдайте порядок написания и чтения. При чтении и записи объекты должны быть в том же порядке сортировки.

Оба они могут вызвать "Unmarshalling unknown type code".

Ответ 3

Если тип списка добавлен, он должен быть:

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

и отпустите его, используя тип класса следующим образом:

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

Ответ 4

В моем случае это исправлено после обновления библиотеки поддержки до 23.2.1

Ответ 5

Это не проблема, связанная с Proguard. Но когда proguard и minify позволяют это выдавать появление всегда.

Проблема заключается в последовательности записи и чтения объекта... последовательность должна быть такой же, как и чтение файла.

Вы можете использовать подключаемый модуль для Android, чтобы сделать класс доступным https://plugins.jetbrains.com/plugin/7332?pr=

Ответ 6

В моем случае это было вызвано размером данных, превышающим максимальный предел, который может быть помещен в парцеллу, которая составляет около 1 МБ.

Решение. Оптимизируйте свой Parcelable код, чтобы как можно меньше данных (например, не помещайте Serializable objects в Parcel)

Ответ 7

В моем случае мой класс не добавляет CREATOR, если он распространяется от другого родителя Parcelable.

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);
        }
}

В поле ImageChild отсутствует поле CREATOR

Ответ 8

Используя 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)
    }
}

Класс 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)
    }
}

}

Ответ 9

Просто удалите все методы parcelable и сгенерируйте их снова с правильной последовательностью

Ответ 10

Просто добавить: эта ошибка также может произойти, когда используются пользовательские представления и неправильно сохраняются/восстанавливаются их состояния с помощью onSaveInstanceState() и onRestoreInstanceState().

Так что, если эта ошибка возникает, также проверьте свои пользовательские представления.