【问题标题】:Reflection using DexClassLoader while linked to external JAR library链接到外部 JAR 库时使用 DexClassLoader 进行反射
【发布时间】:2011-04-01 18:37:18
【问题描述】:

我正在尝试为 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,它就会抛出这个错误。

有人有什么建议吗?

【问题讨论】:

    标签: android plugins dex


    【解决方案1】:

    我可以回答我自己的问题 - 问题是主机和插件都包含外部 jar 库,所以当类加载器发现同一个类有两个版本时,它就会放弃。

    您可以做的是手动构建插件,将所有内容编译为类文件(我让 Eclipse 这样做),然后使用 dex 通过以下方式构建 jar/apk:

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

    projectpath 是你的 android 项目的根目录。当您进入 bin 目录时,应该会找到您的类文件。

    如果有人可以发布一个 ant 脚本来执行此操作,那么添加到这个问题中将是一件好事。

    【讨论】:

      【解决方案2】:

      我用 Maven 解决了同样的问题。 诀窍是仅将公共库包含在主机应用程序中,而不是将其包含在插件中。

      这是我项目的部分 pom。

      公共库 pom

      将其构建为一个 Android 库(使用 apklib 打包)并使用 build-helper-maven-plugin 安装一个额外的 *jar 文件

      <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-plugin 3.2.0 对我来说效果很好

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-17
        相关资源
        最近更新 更多