Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ClassNotFoundException when using custom Parcelable

Tags:

android

I use a custom Parcelable to carry some data to a BroadcastReceiver. Here is what i do:

I register my intent and set the extra Parcelable on it along with an extra classloader (intent.setExtraClassLoader(..)). Next i schedule the execution of the broadcast via an AlarmManager.

So when the AlarmManager fires it looks at my intent with its parcel which it can not process since it doesn't use the supplied classloader (as it seams).

I think the classloader gets lost when Inten.fillIn copys the intent to a new one (see stack trace).

02-21 21:09:25.214: WARN/Intent(52): android.os.BadParcelableException: ClassNotFoundException when unmarshalling: com.company.project.MyParcelable
02-21 21:09:25.214: WARN/Intent(52):     at android.os.Parcel.readParcelable(Parcel.java:1822)
02-21 21:09:25.214: WARN/Intent(52):     at android.os.Parcel.readValue(Parcel.java:1713)
02-21 21:09:25.214: WARN/Intent(52):     at android.os.Parcel.readMapInternal(Parcel.java:1947)
02-21 21:09:25.214: WARN/Intent(52):     at android.os.Bundle.unparcel(Bundle.java:169)
02-21 21:09:25.214: WARN/Intent(52):     at android.os.Bundle.putAll(Bundle.java:242)
02-21 21:09:25.214: WARN/Intent(52):     at android.content.Intent.fillIn(Intent.java:4530)
02-21 21:09:25.214: WARN/Intent(52):     at com.android.server.am.PendingIntentRecord.send(PendingIntentRecord.java:185)
02-21 21:09:25.214: WARN/Intent(52):     at android.app.PendingIntent.send(PendingIntent.java:400)
02-21 21:09:25.214: WARN/Intent(52):     at com.android.server.AlarmManagerService$AlarmThread.run(AlarmManagerService.java:636)

So is there any way around that problem? Any help would be appreciated.

Thanks

like image 332
Moritz Avatar asked Feb 21 '10 21:02

Moritz


3 Answers

Seems that you face with the issue described here: https://code.google.com/p/android/issues/detail?id=6822

There is a workaround described in one of comments under that link: put your custom Parcelable into an additional Bundle. Due to the fact that Bundle internals are not touched until it's needed, such an Intent can be delivered to your app, since nobody will try to unmarshal your class outside your app.

  Bundle hackBundle = new Bundle();
  hackBundle.put("key", myParcelable);
  intent.putExtra("bundleKey", hackBundle);
like image 152
Roman Mazur Avatar answered Nov 17 '22 05:11

Roman Mazur


Put com.company.project.MyParcelable in the actual application, instead of doing whatever games you are playing with classloaders. Then, it should be available from both the sender and recipient of the Intent.

like image 37
CommonsWare Avatar answered Nov 17 '22 05:11

CommonsWare


There is also a bug in Android that can explain this issue in case you try to pass an intent another intent : https://code.google.com/p/android/issues/detail?id=179480&thanks=179480&ts=1436464704

like image 1
Snicolas Avatar answered Nov 17 '22 05:11

Snicolas