使用自定义Parcelable时出现ClassNotFoundException

12
我使用自定义的Parcelable传递数据到BroadcastReceiver。具体步骤如下:
我注册intent并设置带有classloader的额外Parcelable,然后通过AlarmManager安排广播的执行。 当AlarmManager触发时,它查看我的Intent及其Parcel,但无法处理,因为它没有使用提供的classloader(似乎是这样)。 我认为当Intent.fillIn复制意图到新意图时会将classloader丢失 (请参见堆栈跟踪)。
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)

那么有没有解决这个问题的方法?任何帮助都将不胜感激。

谢谢。

3个回答

10

看起来你遇到了这里描述的问题:https://code.google.com/p/android/issues/detail?id=6822

在此链接下的评论中有一种解决方法:将你的自定义Parcelable放入一个额外的Bundle中。由于Bundle的内部在需要之前不会被处理,因此这样的Intent可以传递到你的应用程序,因为没有人会尝试在你的应用程序之外对你的类进行取消标记。

  Bundle hackBundle = new Bundle();
  hackBundle.put("key", myParcelable);
  intent.putExtra("bundleKey", hackBundle);

密钥包和密钥意图必须不同吗? - andresmafra
对我来说它没有起作用。我尝试了这里和6822个Android问题线程讨论中的每个评论。还有其他解决方法吗? - andresmafra

7
com.company.project.MyParcelable放在实际应用程序中,而不是使用类加载器进行任何游戏。然后,它应该可以从Intent的发送者和接收者中获得。

5
哦!我明白了。我没有注意到堆栈跟踪中的这个问题。初步看起来,您不能在PendingIntent中使用自定义的Parcelable对象,这有点糟糕。与其使用Parcelable,您可能需要以其他方式对对象进行序列化(例如,将其序列化为BundleString)。 - CommonsWare
嗯...如果还没有相关问题,您可能需要在http://b.android.com上发布此问题。我无法想象为什么“PendingIntent”会尝试反序列化您的“Parcelable”。 - CommonsWare
这是一个旧的问答,今天在Froyo上帮了我很多。希望这个问题在Gingerbread中得到解决。 - mobibob
有人继续处理这个问题了吗?我遇到了同样的问题。 - bencallis
1
@CommonsWare 我认为AlarmManager这样做的原因是因为它在发送时想要复制Bundle的内容,而你使用Parcel数据的方式就是将其解包并重新打包。执行此操作的代码位于Intent.fillIn()中,并且是最佳努力。如果它能够复制extras,则会这样做,否则它将使用原始的extras,因此您的数据仍然可以安全传递。Intent.fillIn()中的代码注释了它正在执行事情的方式可能会失败,但推迟了修复到未来并说“: -(”。 - cyngus
显示剩余3条评论

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接