选择相册或相机选项时出错:Parcelable写入Serializable对象发生IO异常
崩溃堆栈信息
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.m3h.pmne, PID: 19352 java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.m3h.pmne.ServerResponse.FormParentResponse) at android.os.Parcel.writeSerializable(Parcel.java:1730) at android.os.Parcel.writeValue(Parcel.java:1678) at android.os.Parcel.writeArrayMapInternal(Parcel.java:891) at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1579) at android.os.Bundle.writeToParcel(Bundle.java:1233) at android.os.Parcel.writeBundle(Parcel.java:931) at androidx.fragment.app.FragmentState.writeToParcel(FragmentState.java:125) at android.os.Parcel.writeTypedObject(Parcel.java:1532) at android.os.Parcel.writeTypedList(Parcel.java:1411) at android.os.Parcel.writeTypedList(Parcel.java:1396) at androidx.fragment.app.FragmentManagerState.writeToParcel(FragmentManagerState.java:58) at android.os.Parcel.writeParcelable(Parcel.java:1699) at android.os.Parcel.writeValue(Parcel.java:1605) at android.os.Parcel.writeArrayMapInternal(Parcel.java:891) at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1579) at android.os.Bundle.writeToParcel(Bundle.java:1233) at android.os.Parcel.writeBundle(Parcel.java:931) at android.os.Parcel.writeValue(Parcel.java:1596) at android.os.Parcel.writeArrayMapInternal(Parcel.java:891) at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1579) at android.os.Bundle.writeToParcel(Bundle.java:1233) at android.os.Parcel.writeBundle(Parcel.java:931) at android.os.Parcel.writeValue(Parcel.java:1596) at android.os.Parcel.writeArrayMapInternal(Parcel.java:891) at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1579) at android.os.Bundle.writeToParcel(Bundle.java:1233) at android.app.IActivityManager$Stub$Proxy.activityStopped(IActivityManager.java:3858) at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:144) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:7156) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975) Caused by: java.io.NotSerializableException: com.m3h.pmne.ServerResponse.Data at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1240) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1604) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1565) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1488) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1234) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:354) at android.os.Parcel.writeSerializable(Parcel.java:1725) ... 35 more
错误成因
- 核心逻辑问题:你在触发相机/相册调用的页面(Activity或Fragment)中,将
com.m3h.pmne.ServerResponse.FormParentResponse类型的实例存入了Fragment的Arguments、或者Activity的onSaveInstanceState回调的Bundle中。FormParentResponse虽然实现了Serializable接口,但它内部持有的com.m3h.pmne.ServerResponse.Data类型成员变量没有实现Serializable接口,导致系统序列化整个对象时失败。 - 触发时机:调起系统相机/相册后,你的应用页面被退到后台,系统为了应对后续可能的进程回收,会触发
onSaveInstanceState逻辑执行状态持久化,需要把Bundle内所有数据写入Parcel,此时序列化失败直接抛出异常导致闪退。
可行修复方案
- 方案1:补全
Serializable实现
给ServerResponse.Data类实现Serializable接口,同时要保证Data类内部的所有成员变量的类型也都实现了Serializable接口,否则仍会出现同类报错。建议手动指定serialVersionUID,避免后续类结构变动时出现反序列化不兼容的问题。该方案改动量最小,适合结构简单的实体类。 - 方案2:改用Android平台原生
Parcelable接口实现序列化Parcelable是Android平台专为跨进程、状态保存场景设计的序列化方案,性能远高于Serializable。给FormParentResponse和Data类都实现Parcelable接口即可,若使用Kotlin开发可直接用@Parcelize注解自动生成序列化逻辑,无需手动编写模板代码。 - 方案3:避免将非必要对象存入状态保存Bundle
如果FormParentResponse不需要在页面重建(如屏幕旋转、进程被回收后重启页面)时恢复,就不要将它存入Fragment Arguments或onSaveInstanceState的Bundle中。可以将该类实例存入全局缓存池、ViewModel(ViewModel生命周期独立于页面重建,不会被系统序列化持久化)或者本地持久化层(SharedPreferences、数据库等),需要使用时直接从对应存储读取即可,完全避开系统状态序列化流程。
内容的提问来源于stack exchange,提问作者Md Hafiz
相关产品推荐
相关产品推荐

