【问题标题】:Android Studio dynamically loaded libraryAndroid Studio 动态加载库
【发布时间】:2016-02-23 16:45:16
【问题描述】:

我有一个使用DexClassLoader 动态加载库的Android 应用程序。到目前为止,应用程序和库是在单独的项目中开发的。我想将这些项目合并为一个项目(一个项目中有两个模块?),但我不确定如何使用 Android Studio/Gradle 来实现它。请注意,我不想在应用程序和库之间添​​加静态依赖项。我想要达到的结果是:

  1. 应用程序和库都在同一个项目中。
  2. 应用程序和库的构建可能分两个单独的步骤(但一个步骤可能很好 :D)。
  3. 编译后的库必须最终成为应用程序的资产并捆绑在生成的 APK 中;即,不是静态编译到应用程序中,而是作为 APK 中的独立文件。

有什么想法吗?

【问题讨论】:

    标签: java android gradle shared-libraries dex


    【解决方案1】:

    如果您想将您的模块引入您的项目,您可以在您的项目中编辑文件settings.gradle 以包含该模块并提供其路径。

    include ':app' //your project module name
    include ':library' //your imported module name
    project(':library').projectDir = new File("/<path_to_module_library>/other_project/library")
    

    然后该模块将出现在您的项目中。

    如果您转到您的项目 gradle 文件(例如:build.gradle),您现在可以将您的模块作为您的项目依赖项。

    dependencies {
    ...
       compile project(':library')
    ...
    }
    

    编辑

    如果您只想将 jar 从库中自动复制到项目的 assets 文件夹中,您只需在库 build.gradle 中定义 gradle task 即可:

    task copyTask(type: Sync) {
        from '/<path_to_your_jar>/classes.jar'
        into '/<path_to_your_project>/app/assets/'
    }
    

    这会将您的 jar 复制到您的资产文件夹。

    要在编译代码时使用它,可以将此任务添加到运行/调试配置中。

    【讨论】:

    • 问题是我不希望库模块被静态编译到我的APK中;我希望将其添加为资产,以便稍后手动加载。
    • @FireAphis 啊,我明白了。所以答案 1 和 2 都可以,除了 compile project 应该只是将模块 apk(或 jar)放入 assets 文件夹中,对吧?
    • 第一步看起来正确,我确实想要资产文件夹中的 jar。但是将它添加到依赖项中,它不会将jar静态链接到应用程序中吗?我想避免这种情况。一般来说,说明依赖关系不太重要——没有它我也能应付。但是如何让 gradle 将 jar 复制到资产中?
    【解决方案2】:

    小米的回答给了一个很好的方向,但最终的解决方案有些不同。

    解决方案概述

    该项目将包含两个模块:一个用于应用程序,一个用于库。应用程序模块将依赖于库,因此库将在应用程序之前构建。当 JAR 文件准备好后,它将被转换为 DEX 并复制到应用程序的资产库中。应用程序的构建活动将自动捆绑最终 APK 中的 assets 文件夹。

    分步解决方案

    1. 如果还没有,请将库模块包含在项目设置文件settings.gradle中:

      include ':app', ':libmynewlibrary'
      
    2. app模块的build.gradle中添加依赖:

      dependencies {
          ...
          compile project(':libmynewlibrary')
      }
      
    3. 现在是棘手的部分。我们希望在创建 JAR 后立即添加自定义操作。幸运的是,Android Gradle 插件有一个预定义的任务“jar”——它显然构建了 JAR。我们将在 lib 的 build.gradle 中添加一些内容。请注意,该任务是隐式的,根本不在 gradle 文件中。我们只是通过添加doLast 来扩展它:

      jar {
          doLast {
              exec {
                  executable "dx"
                  args "--verbose", "--dex", "--output=../app/src/main/assets/mynewlib.dex", "build/libs/libmynewlib.jar"
              }
          }
      }
      

    【讨论】:

      猜你喜欢
      • 2017-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多