【问题标题】:ClassNotFoundException when get Parcelable data from broadcast intent从广播意图获取 Parcelable 数据时出现 ClassNotFoundException
【发布时间】:2015-08-12 15:15:36
【问题描述】:

在我的一个班级中,我有一个名为 getResultReceiver() 的方法,它创建了一个 ResultReceiver 的实例:

public class MyTask {

    ResultReceiver resultReceiver;

    public ResultReceiver getResultReceiver() {
          resultReceiver = new ResultReceiver(new Handler()) {
                 @Override
                   protected void onReceiveResult(int resultCode, Bundle resultData) {
                                  …
                    }
            }
            return resultReceiver;
    }
}

我发送带有上述ResultReceiver 实例的广播意图作为额外数据:

Intent intent = new Intent(“my.result.receiver.action”);
intent.putExtra(“my-result-receiver", getResultReceiver());
context.sendBroadcast(intent);

以上所有代码都在主线程之外的另一个线程中运行,MyTask 也由在单独进程中运行的service 实例化。

在我的主要 Activity 类中,我有上述广播意图的广播接收器:

BroadcastReceiver myReceiverInActivity = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.i(“MyApp”, "Reveived broadcast ");
            //Here, I got ClassNotFoundException when unmarshalling : com/xyz/MyTask$1
            ResultReceiver resultReceiver
                                = intent.getParcelableExtra("my-result-receiver");
         }

    };

当我运行我的应用程序时,我可以看到日志“Received broadcast”,但我也得到了一个ClassNotFoundException

FATAL EXCEPTION: main
E/AndroidRuntime( 2649): java.lang.RuntimeException: Error receiving broadcast Intent { act=my.result.receiver.action flg=0x10 (has extras) } in com.xyz.MainActivity$8@18994f97
E/AndroidRuntime( 2649):    at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:882)
E/AndroidRuntime( 2649):    at android.os.Handler.handleCallback(Handler.java:739)
E/AndroidRuntime( 2649):    at android.os.Handler.dispatchMessage(Handler.java:95)
E/AndroidRuntime( 2649):    at android.os.Looper.loop(Looper.java:211)
E/AndroidRuntime( 2649):    at android.app.ActivityThread.main(ActivityThread.java:5373)
E/AndroidRuntime( 2649):    at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 2649):    at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime( 2649):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020)
E/AndroidRuntime( 2649):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)
E/AndroidRuntime( 2649): Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: com.xyz.MyTask$1
E/AndroidRuntime( 2649):    at android.os.Parcel.readParcelableCreator(Parcel.java:2326)
E/AndroidRuntime( 2649):    at android.os.Parcel.readParcelable(Parcel.java:2276)
E/AndroidRuntime( 2649):    at android.os.Parcel.readValue(Parcel.java:2183)
E/AndroidRuntime( 2649):    at android.os.Parcel.readArrayMapInternal(Parcel.java:2516)
E/AndroidRuntime( 2649):    at android.os.BaseBundle.unparcel(BaseBundle.java:221)
E/AndroidRuntime( 2649):    at android.os.Bundle.getParcelable(Bundle.java:755)
E/AndroidRuntime( 2649):    at android.content.Intent.getParcelableExtra(Intent.java:5089)
E/AndroidRuntime( 2649):    at com.xyz.MainActivity$8.onReceive(MainActivity.java:874)
E/AndroidRuntime( 2649):    at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:872)

为什么我得到这个指向MyTask 类的ClassNotFoundException?如何解决?

=====更新======

我尝试了@Samuel 的答案,创建了一个名为MyResultReceiver 的公共类,现在异常几乎相同,但不是$1,而是显示MyResultReceiver

ClassNotFoundException when unmarshalling: com.xyz.MyTask.MyResultReceiver
...

【问题讨论】:

    标签: android android-intent android-activity broadcastreceiver parcelable


    【解决方案1】:

    2 个想法 -

    1- 您是否注册了广播接收器。

    2- 尝试使用 onNewIntent() 方法。

    【讨论】:

    • 1.我已经注册了,不然看不到我提到的日志。
    【解决方案2】:

    接收意图的BroadcastReceiver 与意图的发送者处于不同的进程中,对吗?如果这是真的,它将无法访问您的类,因为它有自己的类加载器。因此ClassNotFoundException。您应该确保两个进程都可以访问其 APK 中的 MyResultReceiver .class 文件。

    【讨论】:

    • 那么,如果我通过 IPC (AIDL) 而不是广播接收器传递 MyResultReceiver 实例,这会是一个解决方案吗?
    • 我不认为改变传输协议会改变任何东西。问题是在接收端,它无权访问定义 MyResultReceiver 的 .class 文件。我将创建一个共享的 .jar 文件,将 MyResultReceiver 放在共享的 .jar 中,并将 .jar 文件包含在两者中进程。
    • 或者您可以重新设计并尝试传输 data 而不是 Java 对象
    • 对了,你说的每个进程都有自己的loader,是不是每个进程都有自己独立的虚拟机实例?
    • 是的,看起来就是这样。看到这个问题stackoverflow.com/questions/13577733/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-11
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-03
    相关资源
    最近更新 更多