Ответ 1
Это из-за обфускации Proguard - обрабатывается Parcelable. Решение: Proguard вызывает RuntimeException (Unmarshalling неизвестный тип кода) в классе Parcelable
У меня сбой приложения на резюме из-за исключения 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?
Это из-за обфускации Proguard - обрабатывается Parcelable. Решение: Proguard вызывает RuntimeException (Unmarshalling неизвестный тип кода) в классе Parcelable
Там есть некоторые правила для написания и чтения посылок.
1- Будьте осторожны с несоответствием типов. Если вы пишете int, не пытайтесь читать долго и т.д.
2- Соблюдайте порядок написания и чтения. При чтении и записи объекты должны быть в том же порядке сортировки.
Оба они могут вызвать "Unmarshalling unknown type code".
Если тип списка добавлен, он должен быть:
@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());
В моем случае это исправлено после обновления библиотеки поддержки до 23.2.1
Это не проблема, связанная с Proguard. Но когда proguard и minify позволяют это выдавать появление всегда.
Проблема заключается в последовательности записи и чтения объекта... последовательность должна быть такой же, как и чтение файла.
Вы можете использовать подключаемый модуль для Android, чтобы сделать класс доступным https://plugins.jetbrains.com/plugin/7332?pr=
В моем случае это было вызвано размером данных, превышающим максимальный предел, который может быть помещен в парцеллу, которая составляет около 1 МБ.
Решение. Оптимизируйте свой Parcelable код, чтобы как можно меньше данных (например, не помещайте Serializable objects в Parcel)
В моем случае мой класс не добавляет 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
Используя 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)
}
}
}
Просто удалите все методы parcelable и сгенерируйте их снова с правильной последовательностью
Просто добавить: эта ошибка также может произойти, когда используются пользовательские представления и неправильно сохраняются/восстанавливаются их состояния с помощью onSaveInstanceState()
и onRestoreInstanceState()
.
Так что, если эта ошибка возникает, также проверьте свои пользовательские представления.