1. 報錯棧 :cusText這個類找不到
2 16:01:29.796 1044 5718 E Parcel : Class not found when unmarshalling: com.cus.sdk.cusText
08-02 16:01:29.796 1044 5718 E Parcel : java.lang.ClassNotFoundException: com.cus.sdk.cusText
08-02 16:01:29.796 1044 5718 E Parcel : at java.lang.Class.classForName(Native Method)
08-02 16:01:29.796 1044 5718 E Parcel : at java.lang.Class.forName(Class.java:454)
2. 解決方案
Message m = getMessage();
Bundle data = m.getData();if (data != null) {// 關鍵:設置與xxx相同的類加載器// 確保使用類本身的類加載器,而不是當前上下文的data.setClassLoader(cusText.class.getClassLoader());
}
3. 解決原理:
這是因為類加載器(ClassLoader)決定了Java虛擬機如何查找和加載類,在跨進程/組件通信場景中,類加載器的不匹配是導致ClassNotFoundException
的常見原因。
為什么需要手動設置類加載器?
Android應用中存在多個類加載器,不同的類加載器負責加載不同來源的類(如系統類、應用自身類、動態加載的插件類等)。默認情況下:
Bundle
在反序列化時會使用當前上下文的類加載器(通常是當前Activity/Service的類加載器)。- 如果
cusText
類是由另一個類加載器加載的(例如:該類來自獨立的庫模塊
、跨進程傳遞的類
、或動態加載的dex
),當前上下文的類加載器可能“不認識”這個類,就會報cusText
找不到。
為什么cusText.class.getClassLoader()
能解決問題?
cusText.class.getClassLoader()
獲取的是實際加載cusText
類的類加載器。通過data.setClassLoader(...)
強制Bundle
使用這個類加載器來反序列化:
- 確保了“加載類的加載器”和“反序列化時的類加載器”是同一個,系統能正確找到類的定義。
- 避免了“當前上下文類加載器”找不到該類的問題(比如跨進程場景中,接收方和發送方的類加載器不同)。
舉個形象的例子:
假設:
cusText
類是由“庫加載器(jar包)”加載的(來自一個獨立的Android Library)。- 當前Activity的類加載器是“應用加載器”,它只認識應用自身的類,不認識“庫加載器”加載的類。
此時:
- 不設置類加載器:
Bundle
用“應用加載器”找cusText
,找不到→報錯。 - 設置
cusText
的類加載器:Bundle
用“庫加載器”找,順利找到→反序列化成功。
這就是為什么手動指定類加載器后,ClassNotFoundException
會被解決——本質是讓系統用“正確的鑰匙(類加載器)”打開“正確的門(找到類)”。