Android中跨進程通訊傳遞Parcelable對象時出現android.os.BadParcelableException: ClassNotFoundException when unmarsh,dllnotfoundexception

來源:互聯網
上載者:User

Android中跨進程通訊傳遞Parcelable對象時出現android.os.BadParcelableException: ClassNotFoundException when unmarsh,dllnotfoundexception

轉載請註明出處:http://blog.csdn.net/bettarwang/article/details/45315091

按Google開發文檔的說法,在跨進程通訊時,推薦使用MessengerService而不是AIDL,所以最近在實現一個跨進程的Service時就採用了MessengerService的方法。

然後定義了這樣一個類:

public class BleServiceBean implements Parcelable {    private String name;    private String uuid;    public BleServiceBean()    {    }    public BleServiceBean(BluetoothGattService service)    {        uuid=service.getUuid().toString();        name= BleNamesResolver.resolveServiceName(uuid);    }    private BleServiceBean(Parcel in)    {        readFromParcel(in);    }    private void writeToParcel(Parcel out)    {        out.writeString(name);        out.writeString(uuid);    }    @Override    public int describeContents()    {        return 0;    }    @Override    public void writeToParcel(Parcel out,int flags)    {        writeToParcel(out);    }    public void readFromParcel(Parcel in)    {        name=in.readString();        uuid=in.readString();    }    public static final Parcelable.Creator<BleServiceBean>CREATOR=new            Parcelable.Creator<BleServiceBean>(){              @Override              public BleServiceBean createFromParcel(Parcel source)              {                  return new BleServiceBean(source);              }              @Override              public BleServiceBean[]newArray(int size)              {                  return new BleServiceBean[size];              }            };}
在Service中擷取到相應資料後要傳遞給UI,有如下代碼:

 Bundle bundle=new Bundle();                bundle.putParcelableArrayList(BleConnectUtils.BLE_SERVICE_BEAN_LIST,beanList);                msg.setData(bundle);                mClients.get(i).send(msg);

在Client端擷取資料的代碼如下:

ArrayList<BleServiceBean>beanList=bundle.getParcelableArrayList(BleConnectUtils.BLE_SERVICE_BEAN_LIST);
但是運行到此處時卻出現如下錯誤:

FATAL EXCEPTION: main
    Process: com.example.xxx.xx, PID: 1203
    android.os.BadParcelableException: ClassNotFoundException when unmarshalling:

給出的出錯原因如下:

Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.xxx.xxx.bean.BleServiceBean" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/vendor/lib, /data/cust/lib, /system/lib]]

後面才發現原來是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。

如果是在要傳遞的JavaBean中有其中一個Field繼承自Parcelable,那麼有很簡單的處理方法,只要把類似rect = in.readParcelable(null);改為config = in.readParcelable(Rect.class.getClassLoader());

但是我們這裡是直接傳遞一個List<BleServiceBean>,那要怎麼辦呢?

其實很簡單,只需要在Client端讀取Bundle中的資料之前加上如下一行代碼:

bundle.setClassLoader(getClass().getClassLoader());
這樣就會使用apk classloader載入。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.