仅部分机型出现Parcelable写入Serializable对象IO异常求助
这个异常看着有点矛盾——明明已经给MyClass实现了Parcelable,怎么系统还在尝试把它当作Serializable来序列化?别急,我帮你梳理几个最可能的原因,按顺序排查应该就能解决:
检查对象传递的方式是否错误
你是不是在Intent或者Bundle里用了putSerializable()/getSerializable()来传递MyClass实例?哪怕你的类实现了Parcelable,一旦调用Serializable相关的方法,系统就会强制按Serializable的规则来处理,而如果MyClass或者它的内部成员没完全适配Serializable,就会抛出这个IO异常。
正确的做法是用Parcelable对应的方法:// 传递时 bundle.putParcelable("my_class_key", myClassInstance); // 获取时 MyClass myClass = bundle.getParcelable("my_class_key");检查MyClass的成员变量是否都支持序列化
即使MyClass本身实现了Parcelable,如果它里面包含的自定义类成员既没实现Parcelable也没实现Serializable,写入Parcel的时候就会触发这个错误。比如你有个private UserInfo userInfo;成员,UserInfo必须也实现其中一个序列化接口,否则系统无法处理它。
另外,如果成员是Serializable类型,但实际赋值的对象没有实现Serializable(比如某个第三方类),同样会出问题。确认Parcelable的实现没有遗漏
有时候我们写Parcelable时会不小心漏写成员变量,或者CREATOR实现有误,导致系统无法正常解析Parcelable,进而 fallback 到Serializable方式。检查这几点:writeToParcel()里是否把所有成员都写入了Parcel?包括私有成员;createFromParcel()是否按写入的顺序读取了所有变量?describeContents()是否返回0(除非你用到了文件描述符,绝大多数场景都是0);CREATOR是否是public static final的,并且正确实现了Parcelable.Creator接口。
排查混淆是否破坏了Parcelable结构
如果你的项目开启了混淆,ProGuard可能会混淆MyClass的Parcelable相关方法或者成员变量,导致系统无法识别它是Parcelable类。需要在proguard-rules.pro里添加规则保护:-keep class mypackage.a.a.a implements android.os.Parcelable { public static final android.os.Parcelable$Creator CREATOR; } -keepclassmembers class mypackage.a.a.a implements android.os.Parcelable { public void writeToParcel(android.os.Parcel, int); public int describeContents(); }
先从第一点开始排查,因为传递方式错误是最常见的原因,然后依次检查后面的点,应该就能找到问题所在了。
内容的提问来源于stack exchange,提问作者Hamidreza Sahraei

