Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BadParcelableException - BroadcastReceiver intent crash

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();
}
like image 790
svguerin3 Avatar asked Jan 16 '13 23:01

svguerin3


1 Answers

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));
    //...
}
like image 102
Andrii Chernenko Avatar answered Sep 27 '22 23:09

Andrii Chernenko