对自定义对象的HashMap进行parcel / unparcel的最佳方法是什么?

时间:2012-07-16 12:08:21

标签: java android ipc classloader parcelable

我有一个Event类定义了这样的私有HashMap

private Map<String, Object> data = new HashMap<String, Object>();

Event类包含在任何类型的“事件”中。此HashMap可以包含由键引用的任何对象实例。接收Event实例的类知道哪个类与每个键相关,因此它可以安全地将Object强制转换为其相应的子类。

当我尝试在两个进程之间传递Event实例时出现问题。 Event实施Parcelable,因此可以通过Message发送:

Bundle bundle = new Bundle();
bundle.putParcelable(Event.BUNDLE_KEY, event);

// Make the message with the bundle
Message message = new Message();
message.setData(bundle);

解组时:

public void readFromParcel(Parcel in) {

    idEvent = in.readInt();
    priority = in.readInt();
    idSource = in.readInt();
    idDestination = in.readInt();
    action = in.readInt();

    Bundle mapBundle = in.readBundle();

    if (mapBundle.getSerializable(MAP_KEY) instanceof HashMap) {
        data = (Map<String, Object>) mapBundle.getSerializable(MAP_KEY);
    } else {
        Log.e(TAG, "Parcel reading error: not a HashMap");
    }
}

问题是这不起作用,因为我需要指定mapBundle使用哪个ClassLoader,例如mapBundle.setClassLoader(Entity.class.getClassLoader());但是我不知道Object会有哪些HashMap子类......

这就是我的想法:

  • 编写一个加载任何这些类的ClassLoader。问题是我无法获得表示对象的byte[],因为它位于HashMap内。并且我无法使用mapBundle.getSerializable()来获取它,因为它会引发ClassNotFound异常。

  • 传递一些额外信息,以便了解HashMap上的哪些课程。除了看起来像冗余信息之外,仍然没有,因为如果我在Bundle上设置一个类加载器,它仍会在其他类上抛出ClassNotFound异常...

我真的很感激这个问题的一些帮助。提前谢谢!

2 个答案:

答案 0 :(得分:1)

实际上this回答了我的问题。我必须得到我的ClassLoader的引用,然后在反序列化上设置它,我认为它是通过另一个线程完成的,可能是一个系统线程,因此它不知道我的类。

答案 1 :(得分:0)

我认为最好的解决方案是重新考虑您的计划,以获得对象的散列图,并根据散列图中的键将它们转换为真实对象。

通过这样做,你不会真正利用java为你提供的类型安全,你也将从HashMap获得额外的开销。

我建议将Event作为接口实现,并让每种类型的Event实现该接口。

这样,类中的“data”变量可以使用描述性名称重命名(这使代码更易于阅读),并且您不必存储任何冗余数据。