簡體   English   中英

Android:將可序列化的對象傳遞給Activity時發生ClassNotFoundException

[英]Android: ClassNotFoundException when passing serializable object to Activity

我有一些來自Android市場的崩潰報告日志,如下所示:

Exception class: java.lang.ClassNotFoundException

Source method: PathClassLoader.findClass()

java.lang.RuntimeException: Unable to start activity ComponentInfo{my.app.package/my.app.package.MyActivity}: java.lang.RuntimeException: Parcelable encounteredClassNotFoundException reading a Serializable object (name = my.app.package.a.ae)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2833)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2854)
at android.app.ActivityThread.access$2300(ActivityThread.java:136)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2179)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:143)
at android.app.ActivityThread.main(ActivityThread.java:5068)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: Parcelable encounteredClassNotFoundException reading a Serializable object (name = my.app.package.a.ae)
at android.os.Parcel.readSerializable(Parcel.java:1951)
at android.os.Parcel.readValue(Parcel.java:1822)
at android.os.Parcel.readMapInternal(Parcel.java:2008)
at android.os.Bundle.unparcel(Bundle.java:208)
at android.os.Bundle.getBundle(Bundle.java:1078)
at android.app.Activity.onRestoreInstanceState(Activity.java:861)
at android.app.Activity.performRestoreInstanceState(Activity.java:835)
at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1135)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2811)
... 11 more
Caused by: java.lang.ClassNotFoundException: my.app.package.a.ae
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:235)
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:2590)
at java.io.ObjectInputStream.readNewClassDesc(ObjectInputStream.java:1846)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:826)
at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:2066)
at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:929)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2285)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2240)
at android.os.Parcel.readSerializable(Parcel.java:1945)
... 19 more
Caused by: java.lang.NoClassDefFoundError: my.app.package.a.ae
... 29 more
Caused by: java.lang.ClassNotFoundException: my.app.package.a.ae in loader dalvik.system.PathClassLoader[.]
at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:243)
at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
at java.lang.ClassLoader.loadClass(ClassLoader.java:532)
... 29 more 

請注意,我使用的是proguard->這就是為什么“缺少”的類名是“ a.ae”的原因。
實際上,“ a.ae”是proguard賦予類“ MyObject”的名稱,如下所示。

為什么會這樣?

我認為這與proguard無關,因為如果這是由proguard類重命名引起的問題,它應該一直存在,並且我可以自己重現此問題。

它與將可序列化的對象傳遞給MyActivity有關嗎?
在MyActivity中

public void onCreate(Bundle savedInstanceState) {  
     myObj = (MyObject) getIntent().getSerializableExtra("nameOfMyObject");  
//here I am trying to read myObj's properties and app seems to crash here  

}


MyObject只是具有幾種類型的類成員的實體,例如:
公共類MyObject實現Serializable {

    /** Generated serialVersionUID */
    static final long serialVersionUID = -267025879233327409L;

    static final String CONSTANT1 = "xpto";

    LinkedHashMap<String, Object> components;

    ArrayList<String> prop1;

    (...)
}

我以以下方式啟動MyActivity:

MyObject obj = new MyObj(stuff);
Intent intent;
intent = new Intent(CurrentActivity.this, MyActivity.class);
intent.putExtra("nameOfMyObject",  obj);
CurrentActivity.this.startActivity(intent);

您是否認為它與對象傳遞的方式有關(作為可序列化的額外內容)?
在找不到其他解決方案的情況下,我想我自己將對象“序列化”為字符串,然后額外傳遞字符串。 你怎么看待這件事?

編輯:我嘗試在模擬器和以下設備中重現此問題,但未成功:

-摩托羅拉Milestone 2 Android 2.2
-三星Galaxy Tab Android 2.2
-沃達豐845 Android 2.1
-HTC Tatoo Android 1.6
-Xperia X10 Android 1.6
-Nexus One Android 2.2
-Google G1 Android 1.5

有什么新主意嗎?

終於在這個問題上得出了一個結論:這是由Proguard引起的,或更具體地說,是因為我沒有合適的Proguard配置。

事實證明,Proguard更改了我的Serializable的類名稱,這使Class.forName(className)失敗。

我必須重新配置我的proguard.cfg文件,並添加以下幾行:

-keep class * implements java.io.Serializable

-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    !static !transient <fields>;
    !private <fields>;
    !private <methods>;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

您應該研究實現Parcelable 這兩個鏈接應該可以幫助您入門: http : //developer.android.com/reference/android/os/Parcel.html http://developer.android.com/reference/android/os/Parcelable.html

LinkedHashMap沒有實現Serializable因此這可能會導致錯誤。 嘗試實施一個小型測試來序列化此類,或者嘗試刪除LinkedHashMap並查看錯誤是否仍然存在。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM