Посылка 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
Ответы
Ответ 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 { *; }