天天看点

android.os.BadParcelableException: ClassNotFoundException when unmarshalling

本文主要分析android.os.badparcelableexception: classnotfoundexception when unmarshalling这个异常的原因及解决方法,解释了android的class loader.

一、现象:

应用打开,home键到后台,过一段时间打开,偶现fc,log如下:

1

2

3

e/androidruntime(9085): caused by: android.os.badparcelableexception: classnotfoundexception when unmarshalling: *.*.*.*.layout$config

e/androidruntime(9085): at android.os.parcel.readparcelable(parcel.java:2077)

e/androidruntime(9085): at *.*.*.<init>(layout.java:105)

程序中的写法是

java

4

5

6

7

public config config;

public rowview(parcel in){

type = in.readstring();

interfaceurl = in.readstring();

size = in.readint();

config = in.readparcelable(null);

}

报错的语句即为config = in.readparcelable(null);

二、原因分析:

根据android文档介绍:

readparcelable (classloader loader)

loader a classloader from which to instantiate the parcelable object, or null for the default class loader.

即loader为空时系统会采取默认的class loader。

android有两种不同的classloaders:framework classloader和apk classloader,其中framework classloader知道怎么加载android classes,apk classloader知道怎么加载you code,apk classloader继承自framework classloader,所以也知道怎么加载android classes。

在应用刚启动时,默认class loader是apk classloader,但在系统内存不足应用被系统回收会再次启动,这个默认class loader会变为framework classloader了,所以对于自己的类会报classnotfoundexception。

三、解决方法:

将config = in.readparcelable(null);改为config = in.readparcelable(config.class.getclassloader());

config.class.getclassloader()即为apk classloader, 其中config.class可以改为你程序中自己写的任意类,因为他们同样指向apk loader

嘿嘿,试着改为config = in.readparcelable(activity.class.getclassloader());你会发现依然classnotfoundexception因为activity.class.getclassloader()指向的是framework classloader

四、如何测试重现这个问题,方便测试呢:

重现这个问题即使的应用被系统回收,把设置->开发者选项->不保留活动开关打开,打开测试程序按home键,再打开测试程序就会执行到这句。

如果你是在onsaveinstancestate中保存

savedinstancestate.putparcelable(key, value),则需要设置bundle的class loader,如下:

savedinstancestate.setclassloader(getclass().getclassloader());

ps:

(1)、readparcelablearray(classloader loader), readparcelable, readarray,readarraylist, readbundle, readhashmap, readparcelable, readsparsearray, readvalue, readlist, readmap也有可能报上面的异常

继续阅读