Obsolete
Status Update
Comments
ye...@gmail.com <ye...@gmail.com> #2
The class loader object in the launch Intent through setExtrasClassLoader() isn't be parceled and pass to ActivityManager. So, the Intent object read from parcel always get a null class loader and create a PathClassLoader from base class path.
I personally think this behavior is reasonable because your class loader object is in your application space and parcel its address across processes isn't reasonable.
But, we still can work around this by marshall/unmarshall data before/after setting/receiving alarms.
I personally think this behavior is reasonable because your class loader object is in your application space and parcel its address across processes isn't reasonable.
But, we still can work around this by marshall/unmarshall data before/after setting/receiving alarms.
ya...@gmail.com <ya...@gmail.com> #3
I have the same issue too. The app worked fine. However, I decided not risk for different platforms.
Android should have better way to pass customized data through intent
Android should have better way to pass customized data through intent
aj...@gmail.com <aj...@gmail.com> #4
Took a peek at the source code that is logging the warning.
android.platform.frameworks.base/core/java/android/content/Intent.java
http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob;f=core/java/android/content/Intent.java;hb=HEAD
5052 try {
5053 Bundle newb = new Bundle(other.mExtras);
5054 newb.putAll(mExtras);
5055 mExtras = newb;
5056 } catch (RuntimeException e) {
5057 // Modifying the extras can cause us to unparcel the contents
5058 // of the bundle, and if we do this in the system process that
5059 // may fail. We really should handle this (i.e., the Bundle
5060 // impl shouldn't be on top of a plain map), but for now just
5061 // ignore it and keep the original contents. :(
5062 Log.w("Intent", "Failure filling in extras", e);
5063 }
This appears to be a legitimate defect based on the supplied comment. Is there an internal bug that was filed?
As many of mentioned in various channels you can marshall/unmarshall manually into a byte[] to work around this defect.
com.platform.packages.apps.DeskClock implements such a work around for it's Alarm Parcelable for use with the system's Alarm Manager Service.
android.platform.frameworks.base/core/java/android/content/Intent.java
5052 try {
5053 Bundle newb = new Bundle(other.mExtras);
5054 newb.putAll(mExtras);
5055 mExtras = newb;
5056 } catch (RuntimeException e) {
5057 // Modifying the extras can cause us to unparcel the contents
5058 // of the bundle, and if we do this in the system process that
5059 // may fail. We really should handle this (i.e., the Bundle
5060 // impl shouldn't be on top of a plain map), but for now just
5061 // ignore it and keep the original contents. :(
5062 Log.w("Intent", "Failure filling in extras", e);
5063 }
This appears to be a legitimate defect based on the supplied comment. Is there an internal bug that was filed?
As many of mentioned in various channels you can marshall/unmarshall manually into a byte[] to work around this defect.
com.platform.packages.apps.DeskClock implements such a work around for it's Alarm Parcelable for use with the system's Alarm Manager Service.
ri...@gmail.com <ri...@gmail.com> #5
I have encountered this same issue. However, my extra is really an Interface object so I can't even rely on any of the workarounds mentioned because I don't know which Class I'm getting on the other side. This should really be handled properly or at the very least documented..
It would save a lot of headaches.
It would save a lot of headaches.
ma...@gmail.com <ma...@gmail.com> #6
A workaround I use is packaging my Parcelable into an additional Bundle, then putting that Bundle into Intent. It works due to the fact that Bundle internals is not unmarshed until it's needed.
Bundle hackBundle = new Bundle();
hackBundle.put("key", myParcelable);
intent.putExtra("bundleKey", hackBundle);
Such an Intent can be successfully delivered to your app from the Alarm manager.
Bundle hackBundle = new Bundle();
hackBundle.put("key", myParcelable);
intent.putExtra("bundleKey", hackBundle);
Such an Intent can be successfully delivered to your app from the Alarm manager.
ri...@gmail.com <ri...@gmail.com> #7
Thank you very much mazur, I can verify that the Parcelable if passed within a bundle isn't unmarshalled so it works and you just saved me from a lot of refactoring!
/hat off to you/
/hat off to you/
an...@gmail.com <an...@gmail.com> #8
[Comment deleted]
an...@gmail.com <an...@gmail.com> #9
I struggled with this problem. The solution is (credit to mazur here in #5):
My target API is 19, and minimum API is 11.
when registering alarm:
Bundle bundle = new Bundle();
bundle.putParcelable("com.foo.alarm", alert);
mNotificationReceiverIntent.putExtra("com.foo.alarm",bundle);
mNotificationReceiverPendingIntent = PendingIntent.getBroadcast(this,
0, mNotificationReceiverIntent, 0);
when receiving the alarm,
Bundle oldBundle = intent.getBundleExtra("com.foo.alarm");
Alert alert = oldBundle.getParcelable("com.foo.alarm");
My target API is 19, and minimum API is 11.
when registering alarm:
Bundle bundle = new Bundle();
bundle.putParcelable("com.foo.alarm", alert);
mNotificationReceiverIntent.putExtra("com.foo.alarm",bundle);
mNotificationReceiverPendingIntent = PendingIntent.getBroadcast(this,
0, mNotificationReceiverIntent, 0);
when receiving the alarm,
Bundle oldBundle = intent.getBundleExtra("com.foo.alarm");
Alert alert = oldBundle.getParcelable("com.foo.alarm");
ct...@google.com <ct...@google.com> #10
What hardware and Android version are you seeing this exception on?
ma...@gmail.com <ma...@gmail.com> #11
I believe it can be reproduced on KitKat and does not depend on hardware.
The problem is that when AlarmThread#run invokes PendingIntent#send, a new Intent is created and populated with Intent#fillIn.
https://android.googlesource.com/platform/frameworks/base/+/android-4.4.4_r2.0.1/services/java/com/android/server/am/PendingIntentRecord.java#210
This makes extras bundle to be unparceled. Hence, if you have a custom Parcelable in that bundle, system process is not able to handle this since it cannot load a class from a different process.
And wrapping your custom Parcelable with a Bundle works due to the fact that Bundle unmarshales its internals only when some key is directly accessed. So the system process does not load a class but just moves bytes around.
The problem is that when AlarmThread#run invokes PendingIntent#send, a new Intent is created and populated with Intent#fillIn.
This makes extras bundle to be unparceled. Hence, if you have a custom Parcelable in that bundle, system process is not able to handle this since it cannot load a class from a different process.
And wrapping your custom Parcelable with a Bundle works due to the fact that Bundle unmarshales its internals only when some key is directly accessed. So the system process does not load a class but just moves bytes around.
en...@google.com <en...@google.com>
ma...@gmail.com <ma...@gmail.com> #12
It would be nice to specify what Android version it's not actual for.
I guess Lollipop.
I guess Lollipop.
[Deleted User] <[Deleted User]> #13
I am observing the same issue on an android 4.3 while creating an Intent for use in a PendingIntent thath is passed to the NfcAdapter.enableForegroundDispatch.
The intent can only be returned to my own app, hence it should be okay to pass classes only known to the ClassLoader of my app. This leaves me wondering why Android unpacks the extra bundle in the first place. As far as I see it should never care about the Extras of an Intent.
I attached a stacktrace.
The intent can only be returned to my own app, hence it should be okay to pass classes only known to the ClassLoader of my app. This leaves me wondering why Android unpacks the extra bundle in the first place. As far as I see it should never care about the Extras of an Intent.
I attached a stacktrace.
[Deleted User] <[Deleted User]> #14
I can confirm that this issue is still happening on Lollipop 5.0.2. I ended up using the Bundle wrapper workaround mentioned above which works fine.
fd...@gmail.com <fd...@gmail.com> #16
Why is this marked as Obsolete? Still an issue on Android N!
je...@plugshare.com <je...@plugshare.com> #17
Seeing this issue on 7.1.1
11...@gmail.com <11...@gmail.com> #18
got it on 8.0
fo...@gmail.com <fo...@gmail.com> #19
Shit! I lost my day thinking that is my fault! Google, fix your bugs
it...@gmail.com <it...@gmail.com> #20
it happens on Android 7 and 8, adding the intent to a PendingIntent to use in a notification. Sadly, I am using a workaround from 2013! http://blog.naboo.space/blog/2013/09/01/parcelable-in-pendingintent/
ra...@gmail.com <ra...@gmail.com> #21
Encountered on Android 13
em...@gmail.com <em...@gmail.com> #22
Encountered on Android 10
Description
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)
The awkward thing though is, that although i receive this error message,
the data object actually does get transfered.
I just shouldn't see that exception imo.
Thanks