当前位置: 首页 > 面试题库 >

Android:将可序列化的对象传递给Activity时,ClassNotFoundException

呼延珂
2023-03-14
问题内容

我有一些来自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);

您是否认为与传递对象的方式有关(作为可序列化的额外内容)?
在找不到其他解决方案的情况下,我想我自己将对象“序列化”为字符串,然后额外传递字符串。你怎么看待这件事?

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

-Motorola Milestone 2 Android 2.2-
三星Galaxy Tab Android 2.2 -Vodafone
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();
}


 类似资料:
  • 问题内容: 我正在尝试将可序列化的对象发送到挂起的Intent。问题是接收到的警报返回为空。即使Alarm实现了可序列化的接口。 收到的警报为空。 编辑:我尝试过的一些其他操作如下,但它似乎不起作用: 收到的警报为空。 问题答案: 我正在使用android Nougat,所以这些答案都没有奏效。我最终将对象传递到字节数组中。 然后我收到了Byte []

  • 问题内容: 我正在尝试将自定义对象从活动传递到片段。我选择实现可序列化并使用以下对象传递对象: 我遇到了错误 尝试在空对象引用上调用虚拟方法 当我尝试将我的对象设置为与活动传递的参数相等时。 这是我的对象 接下来是我要传递的活动,我最终希望传递所有四个对象,但是现在我想至少获得一个成功传递的对象。 然后是引发Null Pointer Exception的片段,我已经用“->”包com.cs246.

  • 问题内容: 我正在尝试将自定义对象从活动传递到片段。我选择实现可序列化并使用以下对象传递对象: 我遇到了错误 尝试在空对象引用上调用虚拟方法 当我尝试将我的对象设置为与活动传递的参数相等时。 这是我的对象 接下来是我要传递的活动,我最终希望传递所有四个对象,但是现在我想至少获得一个成功传递的对象。 然后是引发Null Pointer Exception的片段,我已经用“->”包com.cs246.

  • 本文向大家介绍详解Android中Intent传递对象给Activity的方法,包括了详解Android中Intent传递对象给Activity的方法的使用技巧和注意事项,需要的朋友参考一下 Activity回顾 activity是android程序中最重要的组件之一,它是用户与android用户交互的主要组件,类似于桌面程序的图形界面。android程序大致可以分为看的见的组件和看不见的serv

  • 问题内容: 我正在使用,在网上找到了几个示例。我设法创建此代码以发出请求: 一切正常。但是假设我想将第三个参数传递给该方法,则该参数称为。数据参数是这样的对象: 没有创建该怎么办?我的PHP 等待json输入,因此应该正确发送json。但是我该怎么做呢?谢谢。 问题答案: 您问题的直接答案是:否。方法的签名如下: 公共任务PostAsync(Uri requestUri,HttpContent内容

  • 我需要在rmi服务器中调用一个方法,并从客户端将一个序列化对象传递给该方法,但该对象的类对于服务器来说是未知的