Каков наилучший подход для посылки / разборки HashMap пользовательских объектов?

1

У меня есть класс 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);

Когда unmarshalling:

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 для других классов...

Я бы очень признателен за помощь в этом вопросе. Заранее спасибо!

  • 0
    Класс, используемый в hashmap, должен также реализовывать Parcelable
  • 0
    Оно делает. Это не проблема. Проблема в ClassNotFound, а не в исключении Parcelable.
Теги:
parcelable
ipc
classloader

2 ответа

1
Лучший ответ

На самом деле это отвечает на мой вопрос. Мне нужно получить ссылку на мой ClassLoader, а затем настроить его на де-сериализации, что, я думаю, это сделано через другой поток, возможно, системный поток, и, следовательно, он не знает о моих классах.

0

Я думаю, что лучшим решением является переосмыслить ваш план, чтобы иметь хэш-карту объектов и отбрасывать их на реальные объекты в зависимости от ключа в хэшмапе.

Поступая таким образом, вы действительно не будете использовать типы, которые Java предоставляет для вас, и вы также получите дополнительные накладные расходы из HashMap.

Вместо этого я рекомендовал бы реализовать Событие как интерфейс, и каждый тип события реализует этот интерфейс.

Таким образом, переменная "data" в классах может быть переименована с описательным именем (что упрощает чтение кода), и вам не нужно хранить избыточные данные.

  • 0
    Хммм ... Имейте в виду, что каждое событие может иметь несколько совершенно разных атрибутов. Также это означает необходимость реализации Parcelable для каждого из этих событий. Также это означает, что если новые события разрабатываются позже (что весьма вероятно), я должен создать такие классы, которые бы полностью нарушили обратную совместимость. Кроме того, я не вижу лучшего имени, чем data так как это то, что это: неизвестные данные. Класс Event не заботится о том, что там.
  • 0
    Может быть, вы можете написать обертку, которая просматривает Посылку, прежде чем принять решение о ее распаковке или нет, и если она получит Посылку с idEvent, которой нет в какой-либо таблице поиска, она отбросит эту Посылку?
Показать ещё 6 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню