Java отражение обрабатывает изменения библиотеки
Итак, у меня есть приложение для Android, и я начал создавать систему аддонов для приложения, чтобы разработчики могли кодировать поставщиков контента, которые приложение затем может использовать для генерации другого контента, я не буду проходить через всю процедуру, но все работает нормально, вот так:
1) я создал библиотеку под названием com.myaddonlib
что я импортировал в мой проект, в этой библиотеке есть интерфейс и разные объекты.
2) Теперь разработчик может создать простой Java-проект со своей стороны, импортировать библиотеку com.myaddonlib
и реализовать интерфейс в своем главном классе, который имеет методы, которые возвращают различные объекты из библиотеки.
3) Вернувшись в приложение для Android, я могу загрузить файл.jar, созданный разработчиком (после добавления classes.dex в файл jar), а с помощью android DexClassLoader я могу загрузить реализованный интерфейс следующим образом:
DexClassLoader classloader = new DexClassLoader(jarFilePath, tempDirectory, null, context.getClass().getClassLoader());
Class classToLoad = classloader.loadClass("com.apackage.Addon");
где Addon
это класс, созданный разработчиком аддона, который реализует интерфейс из библиотеки, находящейся в пакете с именем com.apackage
, Затем я могу привести интерфейс из библиотеки com.myaddonlib
к новому экземпляру classToLoad
и вызвать функции, реализованные разработчиком аддона.
Теперь вот проблема, скажем, я решил обновить библиотеку аддонов и удалить одну из переменных из класса, что означает, что класс аддона теперь отличается от класса в обновленной библиотеке (используемой в приложении). Даже если измененная переменная не используется, что-то вызывает сбой приложения без каких-либо ошибок. Просто тот факт, что оба класса различны (даже если единственная разница - просто отсутствующая переменная), приводит к неисправности. Теперь это не простая процедура, чтобы объяснить, так что я бы понял, что, учитывая мой плохой английский, у некоторых возникают проблемы. Моя проблема в том, что мне нужно знать, как избежать этого сбоя из-за смены библиотеки на одном из двух концов. А также как java относится к изменениям объекта в такой ситуации
1 ответ
Мое решение не решает проблему, но гарантирует, что это никогда не произойдет. Проблема, которую вы описываете, напоминает классическую проблему сервер-клиент. У вас есть сервер (в вашем случае приложение, которое вы разрабатываете) и клиенты (надстройки, написанные разработчиками). Вы можете определить интерфейс со многими функциями и передавать данные в двоичных структурах. Это было бы более эффективно с точки зрения трафика / разбора, однако всякий раз, когда вы меняете API на сервере, вам придется обновлять все клиенты (в противном случае возможны сбои или другие проблемы).
Поэтому для решения этой проблемы на сервере-клиенте многие выбирают использование HTTP-вызовов с объектами JSON, которые описывают данные. Хотя этот способ менее эффективен, он позволяет добавлять API и одновременно поддерживать множество клиентских версий.
Использовать этот подход в Android довольно просто. Определите API с двумя функциями и одним интерфейсом:
public String sendDataToLibrary(String jsonString) {
// Parse data, perform operation and return a JSON string as the result
}
public interface GetDataFromLibrary {
String onDataFromLibrary(String jsonString);
}
public void init startLibrary(GetDataFromLibrary callback) {
// Set callback in library and call it whenever you have data that needs to be sent out from the library asynchronously
}
Как вы можете видеть, если вы реализуете этот интерфейс, вы можете передавать любые данные между библиотекой и надстройками, и они никогда не изменятся, поэтому сбои не произойдут. Улучшение может заключаться в том, чтобы принудительно передавать номер версии, чтобы позволить библиотеке поддерживать мульти-версии).