8

This error seems to happen sporadically, which is odd. It usually works fine, but occasionally it creeps up. Here is my code, which is in a BroadcastReceiver:

public void onReceive(Context context, Intent intent) {
    MyCustomResponseMsg message = new MyCustomResponseMsg((MyMessage) intent.getParcelableExtra(MyMessage.EXTRA_MESSAGE_KEY));

    // do stuff with the message

    setResultCode(Activity.RESULT_OK);
}

And here is the exception:

01-16 10:05:03.834: ERROR/AndroidRuntime(13533): FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start receiver com.(path-to-broadcast-receiver).MyReqReceiver:   
android.os.BadParcelableException: ClassNotFoundException when unmarshalling:  com.(path-to-my-message).MyMessage
at android.app.ActivityThread.handleReceiver(ActivityThread.java:1805)
at android.app.ActivityThread.access$2400(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:981)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3683)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling:     com.(path-to-my-message).MyMessage
at android.os.Parcel.readParcelable(Parcel.java:1958)
at android.os.Parcel.readValue(Parcel.java:1846)
at android.os.Parcel.readMapInternal(Parcel.java:2083)
at android.os.Bundle.unparcel(Bundle.java:208)
at android.os.Bundle.getParcelable(Bundle.java:1100)
at android.content.Intent.getParcelableExtra(Intent.java:3437)
at     com.(path).MyReceiver.onReceive(My    ReqReceiver.java:23)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:1794)
... 10 more

The error seems to occur on the getParcelableExtra line. The "MyMessage" class (obviously named something different in my own project) does indeed exist; it's contained in an library. It works most of the time, but there are times when I can get this to crash every time the broadcast is received.

I realize this isn't much to go off of, but I just wanted to see if there's anything I could be doing differently in the receiver to capture this so that it doesn't cause a crash. Or if it's definitely something on the side of sending the Broadcast, then I can focus on that if needed. But in the interim, I just wanted to make sure this was setup properly for my purposes. I've checked other similar posts with this crash, but I can't seem to find any that involve this specific kind of parcelable getting from the intent in a BroadcastReceiver.

Thanks in advance for any guidance on this!

EDIT Here is what the constructor for MyMessage looks like, if needed:

public MyMessage(Parcel in) {
    field1 = in.readInt();
    field2 = in.readString();
    field3 = in.readString();
}
svguerin3
  • 2,433
  • 3
  • 29
  • 53

1 Answers1

8

Most of the cases of this issue I've seen were resolved by setting the correct ClassLoader in process of unmarshalling your custom Parcelable class.

Have a closer look at your MyMessage constructor, specifically on how you obtain ClassLoader:

private MyMessage(Parcel in) {
    //...
    //causes ClassNotFoundException
    this.field=in.readParcelable(null); 
    //causes ClassNotFoundException, in fact it's equivalent to previous
    this.field=in.readParcelable(ClassLoader.getSystemClassLoader()); 

    //this one should work
    this.field=in.readParcelable(getClass().getClassLoader());
}

More details can be found in this question.


UPDATE: Also, try setting correct ClassLoader for Bundle contained in your Intent:

public void onReceive(Context context, Intent intent) {
    Bundle extras=intent.getExtras();
    extras.setClassLoader(getClass().getClassLoader());
    MyCustomResponseMsg message = new MyCustomResponseMsg((MyMessage) extras.getParcelable(MyMessage.EXTRA_MESSAGE_KEY));
    //...
}
Community
  • 1
  • 1
Andrii Chernenko
  • 9,873
  • 7
  • 71
  • 89
  • Ah that makes sense. I updated my question to actually contain what the constructor looks like for MyMessage. Seems as if this code is just using the standard "readString()" and "readInt()" methods. Curious if those should be changed? I'd be wary to do so, since this MyMessage class is used in MANY different places throughout our application framework. So I'm hoping there's a solution that doesn't involve touching the MyMessage class? I'll read deeper in the meantime to familiarize myself more about the unmarshalling process. – svguerin3 Jan 17 '13 at 00:59
  • Unfortunately even while adding the setting of the ClassLoader in the onReceive for the Intent, the crash still occurs with the same BadParcelableException. :( Now I'm really stumped. I appreciate your help with this regardless. Any other thoughts, by any chance? – svguerin3 Jan 17 '13 at 16:36
  • 3
    Finally got this resolved. Turns out the SDK library containing the MyMessage class was moved to a different namespace. Somehow it was still holding onto it from this app, even after several Rebuilds of the project! I uninstalled all apps and the SDK, and I re-installed everything, and then it found it ok and this exception stopped occurring. I will still mark this answer as correct, as it is indeed the right approach to the solution. Thanks again! – svguerin3 Jan 17 '13 at 17:43