天天看點

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也有可能報上面的異常

繼續閱讀