3

In one of my class, I have a method called getResultReceiver() which created an instance of ResultReceiver:

public class MyTask {

    ResultReceiver resultReceiver;

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

I send an broadcast intent with the above ResultReceiver instance as an extra data:

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

All the above code is running in another thread than main thread, the MyTask is instantiated by a service running in a separate process as well.

In my main Activity class, I have the broadcast receiver for above broadcast intent:

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");
         }

    };

When I run my app, I can see the log “Received broadcast”, but I also got an 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)

Why I got this ClassNotFoundException that points to MyTask class? how to resolve it?

=====UPDATE======

I tried @Samuel 's answer, made an public class named MyResultReceiver, now the exception is almost the same, but instead of $1 , it shows MyResultReceiver:

ClassNotFoundException when unmarshalling: com.xyz.MyTask.MyResultReceiver
...
user842225
  • 5,445
  • 15
  • 69
  • 119

2 Answers2

0

2 Ideas -

1- Have you registered your broadcast receiver.

2- Try using the onNewIntent() method.

KISHORE_ZE
  • 1,466
  • 3
  • 16
  • 26
0

The BroadcastReceiver receiving the intent is in a separate process from the sender of the intent, correct? If that's true it won't have access to your class because it has its own class loader. Hence the ClassNotFoundException. You should make sure that both processes have access to the MyResultReceiver .class file in their APK.

Samuel
  • 16,923
  • 6
  • 62
  • 75
  • So, if I pass `MyResultReceiver` instance through IPC (AIDL)instead of broadcast receiver, could it be a solution? – user842225 Aug 12 '15 at 15:53
  • I don't think changing the transport protocol is going to change anything. The problem is that on the receiving side, it doesn't have access to the .class file that MyResultReceiver is defined in. I would create a shared .jar file, put MyResultReceiver in the shared .jar and include the .jar file in both processes. – Samuel Aug 12 '15 at 15:58
  • Or you could redesign and try to transport *data* instead of a Java object – Samuel Aug 12 '15 at 15:59
  • By the way, as you said each process has its own loader, does it mean also each process has its independent virtual machine instance? – user842225 Aug 12 '15 at 16:23
  • Yes it looks to be that way. See this question http://stackoverflow.com/questions/13577733/how-an-android-application-is-executed-on-dalvik-virtual-machine – Samuel Aug 12 '15 at 16:58