android 开发之坑系列_实体序列化问题
16lz
2021-01-23
坑一:实体序列化问题
详情:
java.lang.RuntimeException: Unable to start activity ComponentInfo{app.android.test/app.android.test.activity.MainActivity}: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2377)at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2429)at android.app.ActivityThread.access$800(ActivityThread.java:151)at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1342)at android.os.Handler.dispatchMessage(Handler.java:110)at android.os.Looper.loop(Looper.java:193)at android.app.ActivityThread.main(ActivityThread.java:5333)at java.lang.reflect.Method.invokeNative(Native Method)at java.lang.reflect.Method.invoke(Method.java:515)at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)at dalvik.system.NativeStart.main(Native Method)****Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: ****at android.os.Parcel.readParcelableCreator(Parcel.java:2154)at android.os.Parcel.readParcelable(Parcel.java:2104)
实体序列化代码:
`public class HomeDataItem implements Parcelable { public BannerGroup bannerGroup; public List agility; public AppSpecial special; public Variety variety; public DiscoverBanner banner; public int showType; public int type; public TrafficConfig mTrafficConfig; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { bannerGroup = in.readParcelable(BannerGroup.class.getClassLoader()); agility = in.createTypedArrayList(Agility.CREATOR); special = in.readParcelable(AppSpecial.class.getClassLoader()); variety = in.readParcelable(Variety.class.getClassLoader()); banner = in.readParcelable(DiscoverBanner.class.getClassLoader()); showType = in.readInt(); mTrafficConfig = in.readParcelable(TrafficConfig.class.getClassLoader()); type = in.readInt(); } protected HomeDataItem(Parcel in) { dest.writeParcelable(bannerGroup, flags); dest.writeTypedList(agility); dest.writeParcelable(special, flags); dest.writeParcelable(variety, flags); dest.writeParcelable(banner, flags); dest.writeInt(showType); dest.writeInt(type); dest.writeParcelable(mTrafficConfig, flags); } public static final Creator CREATOR = new Creator() { @Override public HomeDataItem createFromParcel(Parcel source) { return new HomeDataItem(source); } @Override public HomeDataItem[] newArray(int size) { return new HomeDataItem[size]; } };}`
从上面不知道大家看出什么门道没,反正当时一脸不知道哪里出了问题,本地测试没有问题,线上就出现问题了,而且还不早,崩溃一下提升到6%,必须解决啊,然后各种查,最后终于发现了是,序列化时,写与读不对称问题,这里我也不知道是咋原因,知道的同学下面留言下(^)!
protected HomeDataItem(Parcel in) { bannerGroup = in.readParcelable(BannerGroup.class.getClassLoader()); agility = in.createTypedArrayList(Agility.CREATOR); special = in.readParcelable(AppSpecial.class.getClassLoader()); variety = in.readParcelable(Variety.class.getClassLoader()); banner = in.readParcelable(DiscoverBanner.class.getClassLoader()); showType = in.readInt(); //原来的位置 type = in.readInt(); mTrafficConfig = in.readParcelable(TrafficConfig.class.getClassLoader());}@Overridepublic void writeToParcel(Parcel dest, int flags) { dest.writeParcelable(bannerGroup, flags); dest.writeTypedList(agility); dest.writeParcelable(special, flags); dest.writeParcelable(variety, flags); dest.writeParcelable(banner, flags); dest.writeInt(showType); dest.writeInt(type); dest.writeParcelable(mTrafficConfig, flags);}
重现问题:
重现这个问题即使的应用被系统回收,把设置->开发者选项->不保留活动开关打开,打开测试程序按home键,再打开测试程序就会执行到这句。
相关知识:
Android有两种不同的classloaders:
- framework classloader
- apk classloader
其中framework classloader知道怎么加载android classes,apk classloader知道怎么加载你自己的代码,而apk classloader继承自framework classloader,所以也知道怎么加载android classes。
而在应用刚启动时,默认class loader是apk classloader,但在系统内存不足应用被系统回收会再次启动,这个默认class loader会变为framework classloader了,它就加载不到你自己的代码里面的类,所以会报ClassNotFoundException。
这个是在这边文章中提到的,具体可以看下,但是为什么序列化不按规定会有问题还是不解,在这里先记录着。
更多相关文章
- android中如何在代码中直接设置View的layout_weight属性
- Android震动代码解读
- android 学习笔记有用代码片段(2)
- android 关于gallery 的平滑代码滚动
- Android客户端自动更新代码
- [CSDN]Android应用程序启动过程源代码分析
- android连续按两次返回退出程序(完整代码)
- Android 加载图片文件 函数
- Android Java代码执行adb Shell命令