У меня есть класс 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
для других классов...
Я бы очень признателен за помощь в этом вопросе. Заранее спасибо!
На самом деле это отвечает на мой вопрос. Мне нужно получить ссылку на мой ClassLoader, а затем настроить его на де-сериализации, что, я думаю, это сделано через другой поток, возможно, системный поток, и, следовательно, он не знает о моих классах.
Я думаю, что лучшим решением является переосмыслить ваш план, чтобы иметь хэш-карту объектов и отбрасывать их на реальные объекты в зависимости от ключа в хэшмапе.
Поступая таким образом, вы действительно не будете использовать типы, которые Java предоставляет для вас, и вы также получите дополнительные накладные расходы из HashMap.
Вместо этого я рекомендовал бы реализовать Событие как интерфейс, и каждый тип события реализует этот интерфейс.
Таким образом, переменная "data" в классах может быть переименована с описательным именем (что упрощает чтение кода), и вам не нужно хранить избыточные данные.
data
так как это то, что это: неизвестные данные. Класс Event
не заботится о том, что там.