如何修复 Android 中偏移 YYY 处的 Unmarshalling unknown type code XXX?
Posted
技术标签:
【中文标题】如何修复 Android 中偏移 YYY 处的 Unmarshalling unknown type code XXX?【英文标题】:How to fix Unmarshalling unknown type code XXX at offset YYY in Android? 【发布时间】:2014-03-17 16:27:07 【问题描述】:由于 Unmarshalling 异常,我在恢复时遇到应用程序崩溃。我检查了所有可序列化的构造函数都没有参数,甚至使用 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.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 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
保存的数据由Bundle
s 和Serializable
s 组成,它们看起来都不错。
我会做下一个:
try
// unmarshalling
catch (Throwable t)
// look offset
我如何理解 Parcelable 偏移的实际类型是什么?
【问题讨论】:
这发生在我身上,因为我没有从我的 Parcel 中读取一个 int 值(但正在写入它)。它搞砸了一切,应用程序崩溃了。 【参考方案1】:有一些读写parcelables的规则。
1- 注意类型不匹配。如果你写 int,不要试图读 long 等。
2- 注意写入和读取的顺序。对象在读写时必须处于相同的排序顺序。
这两种情况都可能导致“Unmarshalling unknown type code”。
【讨论】:
这是我的解决方案:注意写入和读取的顺序。对象在读写时必须处于相同的排序顺序。 3 - 如果有 Parcelable 类型的字段,请注意写入和读取的顺序。 Parcelable 类型的字段在读写时必须保持相同的排序顺序。 因为异常可能发生在堆栈跟踪显示不完全的地方。例如:堆栈跟踪显示字段 A 导致异常,但实际上是 parcelable 类型的字段 B 导致异常。 由于这个答案有这么多投票,我将分享我的救命稻草超过 5 年。 parcelabler.com。肯定还有其他网站,但我正在使用这个。【参考方案2】:这是因为 Proguard 混淆 - 它处理 Parcelable。 解决方案:Proguard causing RuntimeException (Unmarshalling unknown type code) in Parcelable class
【讨论】:
同样的问题,但它在调试时发生,所以这不是我的解决方案 - 另一个想法? @Srneczek 你找到解决方案了吗?是否也仅在 6.x 或其他版本上发生过? @ab.helly 不,我不记得是什么问题 - 如果我再次遇到这个问题,我可以回答你,但我想我使用了另一种方法来避免解组问题 对于它的价值,它也可能是你的实现。我最近在编写的自定义 ViewGroup 中遇到了这个问题。我没有使 CREATOR 成为静态的,所以当 Activity 被销毁时它会在旋转时抛出这个错误。通过在开发者选项中打开“不保留活动”很容易复制。 @worked 这可能是由于对 Parcel 的一些读取/写入。就我而言,我正在给 Parcel 写信,但没有从中读取。恢复实例状态时会导致混乱。【参考方案3】:如果添加了一个List类型,应该是:
@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());
【讨论】:
如果在将 List 添加到实现 Parcelable 的类中后出现此错误,那么这就是为我解决的问题。【参考方案4】:在我的情况下,它在将支持库升级到 23.2.1 后得到修复
【讨论】:
我想知道是什么问题,因为我在developer.android.com/topic/libraries/support-library/…没有看到任何相关问题【参考方案5】:这不是 Proguard 相关的问题。但是当 proguard 和 minify 启用时,它的问题总是发生。
问题在于对象的写入和读取顺序...顺序应该相同,就像读取文件一样。
您可以使用 android studio 插件将 class 设为 parcelable https://plugins.jetbrains.com/plugin/7332?pr=
【讨论】:
我浪费了几个小时来解决这个问题。我遇到了同样的问题,你的建议救了我读写顺序应该是一样的【参考方案6】:在我的情况下,我的班级在从另一个 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);
在 ImageChild 中缺少 CREATOR 字段
【讨论】:
【参考方案7】:只需删除所有可打包的方法并使用有效序列再次生成它们
【讨论】:
【参考方案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】:在我的情况下,这是由于数据大小超过了可以放入 Parcel 的最大限制(大约 1 MB)引起的。
解决方案:优化 Parcelable 代码以尽可能少地放入数据(例如,不要将 Serializable 对象放入 Parcel)
【讨论】:
【参考方案10】:补充一点:当使用自定义视图并且未通过onSaveInstanceState()
和onRestoreInstanceState()
正确保存/恢复其状态时,也会发生此错误。
因此,如果发生此错误,请同时检查您的自定义视图。
【讨论】:
对我来说,这是关于自定义视图之一中 CREATOR 字段的错误声明。【参考方案11】:父模型有parcelable,子模型有parcelable,然后使用下面的代码可以正常工作并且不会出现解组错误
父模型
data class ParentModel(
@SerializedName("post_id") val post_id: String? = "",
@SerializedName("images") val images: ArrayList<ChildModel>? = null
) : Parcelable
constructor(parcel: Parcel) : this(
parcel.readString(),
parcel.createTypedArrayList(ChildModel.CREATOR)!!
)
override fun writeToParcel(parcel: Parcel, flags: Int)
parcel.writeString(post_id)
parcel.writeTypedList(images)
override fun describeContents(): Int
return 0
companion object CREATOR : Parcelable.Creator<ParentModel>
override fun createFromParcel(parcel: Parcel): ParentModel
return ParentModel(parcel)
override fun newArray(size: Int): Array<ParentModel?>
return arrayOfNulls(size)
儿童模型
data class ChildModel(
@SerializedName("image_id") val image_id: String? = "",
@SerializedName("image_url") val image_url: String? = ""
) : Parcelable
constructor(parcel: Parcel) : this(
parcel.readString(),
parcel.readString()
)
override fun writeToParcel(parcel: Parcel, flags: Int)
parcel.writeString(image_id)
parcel.writeString(image_url)
override fun describeContents(): Int
return 0
companion object CREATOR : Parcelable.Creator<ChildModel>
override fun createFromParcel(parcel: Parcel): ChildModel
return ChildModel(parcel)
override fun newArray(size: Int): Array<ChildModel?>
return arrayOfNulls(size)
【讨论】:
以上是关于如何修复 Android 中偏移 YYY 处的 Unmarshalling unknown type code XXX?的主要内容,如果未能解决你的问题,请参考以下文章