Java Android:ClassNotFoundException将可序列化对象传递给活动时

Java Android:ClassNotFoundException将可序列化对象传递给活动时,java,android,exception,Java,Android,Exception,我在android market上有一些类似的崩溃报告日志: 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.Runt

我在android market上有一些类似的崩溃报告日志:

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有关吗
在我的活动中,我有

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实现可序列化{

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

    static final String CONSTANT1 = "xpto";

    LinkedHashMap<String, Object> components;

    ArrayList<String> prop1;

    (...)
}
您认为这与对象的传递方式(作为可序列化的额外对象)有关吗?
如果我找不到任何其他解决方案,我想我会自己将对象“序列化”为字符串,然后额外传递字符串。 你觉得这个怎么样

编辑:我试图在模拟器和以下设备中重现此问题,但未成功:

-摩托罗拉里程碑2安卓2.2
-三星Galaxy Tab安卓2.2
-沃达丰845安卓2.1
-HTC塔图安卓1.6
-Xperia X10安卓1.6
-Nexus One Android 2.2
-谷歌G1安卓1.5


有什么新想法吗?

LinkedHashMap
没有实现
Serializable
,因此这可能会导致错误。请尝试实现一个小测试来序列化这个类,或者尝试删除
LinkedHashMap
,看看错误是否仍然存在。

您应该研究如何实现
Parcelable
。 以下两个链接将帮助您开始:
http://developer.android.com/reference/android/os/Parcelable.html

最终得出了关于这个问题的结论:它是由Proguard引起的,或者更具体地说,因为我没有propper 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();
}
-keep class*实现java.io.Serializable
-keepclassmembers类*实现java.io.Serializable{
静态最终长SerialVersionId;
私有静态final java.io.ObjectStreamField[]serialPersistentFields;
!静态!瞬态;
私有的
私有的
私有void writeObject(java.io.ObjectOutputStream);
私有void readObject(java.io.ObjectInputStream);
java.lang.Object WriterReplace();
java.lang.Object readResolve();
}

你的对象是可序列化的吗?我们需要一些代码来看看你想做什么…@Flo:是的,我的对象是可序列化的Serializable@Beasly:
public void onCreate(Bundle savedInstanceState){myObj=(MyObject)getIntent().getSerializableExtra(“nameOfMyObject”);//这里我试图读取myObj的属性,而应用程序似乎在这里崩溃了}
编写一个快速测试类,对对象进行序列化,然后取消序列化,以确认链中没有导致问题的类。感谢您的提示。我将尝试此方法,但主要问题是我无法重现问题,因此我甚至无法确定我找到的任何解决方案是否有效关于这个问题:(这就是我在尝试Proguard更改后最终解决类似故障的方式。在将近2年后,你救了我的一天好友..谢谢+1。我也很感激你对发布自己答案的态度官方Proguard解释:如果Proguard未启用怎么办?这个错误仍然在发生我在一些三星设备上也遇到了这个问题。)而Progurd被禁用。
-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();
}