Отражение с использованием DexClassLoader при подключении к внешней библиотеке JAR - PullRequest
4 голосов
/ 01 апреля 2011

Я пытаюсь собрать архитектуру плагина для приложения Android. У меня есть хост-приложение, которое будет проверять каталог для apk «плагинов», загружать их в DexClassLoader и вызывать метод для получения массива DerivedLibraryObjects.

Я думаю, что проблема в том, что DerivedLibraryObject расширяет базовый класс, который содержится во внешней библиотеке JAR. Так что и хост, и плагин ссылаются на этот JAR. Когда я пытаюсь получить массив DerivedLibraryObjects, я получаю следующее исключение:

04-01 14:26:57.996: ERROR/AndroidRuntime(23386): java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation

Из того, что я понял, это означает, что объект в плагине не соответствует объекту в хосте. Однако приложения хоста и плагина ссылаются на копию одного и того же файла JAR. Если я возвращаю объект, который просто расширяет Object, тогда код работает нормально, но как только я начинаю работать с DerivedLibraryObject, он выдает эту ошибку.

У кого-нибудь есть предложения?

Ответы [ 2 ]

4 голосов
/ 02 апреля 2011

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

ЧтоВы можете создать свой плагин вручную, скомпилировав все в файлы классов (я позволил Eclipse сделать это), а затем собрав jar / apk с помощью dex:

dx --dex --output=<outputdir>\plugin.jar <projectpath>\bin\

projectpath - корень вашего проекта Android.Ваши файлы классов должны быть найдены, когда вы спускаетесь в каталог bin.

Если кто-то может опубликовать для этого сценарий ant, это было бы неплохо добавить к этому вопросу.

0 голосов
/ 24 мая 2012

Мне удалось решить ту же проблему с Maven.Хитрость заключается в том, чтобы включить общую библиотеку только в хост-приложение, а не включать ее в плагин.

Здесь представлены части моих проектов.

общая библиотека pom

соберите ее как библиотеку andriod (используя упаковку apklib) и установите дополнительный файл * jar с помощью build-helper-maven-plugin

<plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>build-helper-maven-plugin</artifactId>
   <version>1.7</version>
   <executions>
      <execution>
         <id>attach-artifacts</id>
         <phase>package</phase>
         <goals>
            <goal>attach-artifact</goal>
         </goals>
         <configuration>
            <artifacts>
               <artifact>
                  <file>${basedir}/target/${project.build.finalName}.jar</file>
                  <type>jar</type>
               </artifact>
            </artifacts>
         </configuration>
      </execution>
   </executions>
</plugin>

pom хост-приложения включает зависимость от общей библиотеки

<dependency>
   <groupId>group.id</groupId>
   <artifactId>artifact-id</artifactId>
   <version>common-library-version</version>
   <type>apklib</type>
</dependency>

pom плагина использует * .jar зависимость с предоставленной областью действия.Зависимость Apklib не поддерживает предоставленную область.

<dependency>
   <groupId>your.common.library.group</groupId>
   <artifactId>Your-common-lib-id</artifactId>
   <version>your-common-lib-version</version>
   <scope>provided</scope>
</dependency>

Окончательно создайте какой-нибудь ассемблерный проект и включите в его pom-файл все три проекта.

Он отлично работает для меня нас maven3 и android-maven-плагином 3.2.0

...