Подтвердить что ты не робот

Посылка Unmarshalling неизвестного типа кода

Мы получаем эту ошибку в отчетах о сбоях, зарегистрированных в магазине воспроизведения. Невозможно воспроизвести это во всех наших тестах. Есть ли у кого-то еще одна проблема или решение? Дело в том, что мы даже не знаем, что делать, чтобы воспроизвести эту ошибку.

Все объекты Parableable имеют CREATOR, writeToParcel() и contructor. Все списки и сложные типы инициализируются и нуль проверяется.

java.lang.RuntimeException: Unable to start activity ComponentInfo{au.com.company/au.com.company.DetailsActivity}: java.lang.RuntimeException: Parcel [email protected]: Unmarshalling unknown type code 6881381 at offset 11268
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2247)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2297)
at android.app.ActivityThread.access$700(ActivityThread.java:152)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1282)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5328)
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:1102)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: Parcel [email protected]: Unmarshalling unknown type code 6881381 at offset 11268
at android.os.Parcel.readValue(Parcel.java:2032)
at android.os.Parcel.readMapInternal(Parcel.java:2225)
at android.os.Bundle.unparcel(Bundle.java:223)
at android.os.Bundle.getSparseParcelableArray(Bundle.java:1240)
at android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:861)
at android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:1104)
at android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:1086)
at android.support.v4.app.FragmentManagerImpl.dispatchCreate(SourceFile:1872)
at android.support.v4.app.FragmentActivity.onCreate(SourceFile:215)
at android.support.v7.app.ActionBarActivity.onCreate(SourceFile:97)
at au.com.company.DetailsActivity.onCreate(SourceFile:40)
at android.app.Activity.performCreate(Activity.java:5250)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1097)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
... 11 more
4b9b3361

Ответ 1

У меня возникла проблема с пользовательским представлением, имеющим собственную реализацию View.BaseSavedState. Оказалось, что метод writeToParcel() имел вызовы методов в неправильном порядке.

Было неприятно найти проблему, и мне нужно было отладить Android SDK до класса Bundle, где unparcel() вызывается:

synchronized void unparcel() {
    if (mParcelledData == null) {
        return;
    }

    int N = mParcelledData.readInt();
    if (N < 0) {
        return;
    }
    if (mMap == null) {
        mMap = new HashMap<String, Object>(N);
    }
    mParcelledData.readMapInternal(mMap, N, mClassLoader);
    mParcelledData.recycle();
    mParcelledData = null;
}

Строка 223 вашего журнала - это именно вызов readMapInternal(). Там объект Parcel будет перебирать свои элементы, считывая значения один за другим. Проблема обычно возникает, если что-то было написано в неправильном порядке. Метод Parcel.readValue(загрузчик ClassLoader) будет читать их в том порядке, в котором они были записаны, но если у вас есть пользовательские представления или объекты, если они были написаны в порядке, отличном от того, который вы сейчас читаете, что-то не так произойдет в СЛЕДУЮЩИЙ пункт для чтения.

Итак, я нашел проблему, идентифицировав последний элемент, который был прочитан успешно. Обычно вы можете определить это (если это пользовательский вид или объект), проверив его имя класса создателя. Проверьте метод класса Parcel readParcelableCreator():

public final <T extends Parcelable> Parcelable.Creator<T> readParcelableCreator(
        ClassLoader loader) {
    String name = readString();
    if (name == null) {
        return null;
    }
...
}

Вы можете проверить строку имени для класса создателя. Если это обычная, вы можете сразу ее идентифицировать. Затем, если следующее чтение приведет к сбою вашего приложения, вы можете быть почти уверены, что виновником было предыдущее чтение.

Надеюсь, что это поможет.

Ответ 2

Я также получил эту ошибку, но я нашел проблему. Я изменил переменную от long до int, но забыл изменить следующее:

Я имел parcel.writeLong(number), а затем прочитал его как number=parcel.readInt(). Правильно - parcel.writeInt(number).

Ответ 3

Проверьте порядок ваших read и write в своих классах Parcelable и соответствующих подклассах.

Порядок, в котором вы writeToParcel должен быть тем же самым порядком, который вы читаете в своем методе MyParcelable(Parcel in).

Ответ 4

Я получил эту ошибку, когда я перечитал источник Parcel, чтобы сохранить на карте вместо проверки возвращаемого значения null:

String tag = in.readString();
Double value = in.readDouble();
while (tag != null && value != null) {
    this.observations.put(tag, value);
    tag = in.readString();
    value = in.readDouble();
};

Следует хранить int для правильной итерации на Parcel:

int numObservations = in.readInt();
String key;
Double value;
for (int i = 0; i < numObservations; i++) {
    key = in.readString();
    value = in.readDouble();
    map.put(tag, value);
}

Ответ 5

Я получил ту же ошибку при считывании посылки.

Проверьте порядок и количество во время чтения/записи ваших классов Parcelable и соответствующих подклассов.

Ответ 6

Если у вас есть собственный класс SavedState, убедитесь, что он не является Proguarded, и он не является атрибутом CREATOR static.

Используйте что-то вроде:

# Keeping *SavedState and *SavedState#CREATOR
-keep public final class * extends android.view.AbsSavedState
-keepclassmembers public final class * extends android.view.AbsSavedState { *; }