如何在库模块中将库/*.jar、依赖库和我的 java/kotlin 代码文件编译为 dex?



我想将libs/*.jar,依赖库和我的java/kt代码文件编译为库模块中的dex,然后android应用程序可以下载这些dex文件,然后通过DexClassLoader动态加载它们。

Android Studio 提供了一个 Gradle 任务"dexRelease",将我自己的代码文件编译成 dex 文件,但无法将 libs/*.jar 和依赖库编译成 dex 文件。

gradlew testsdk:dexRelease

我希望将库/*.jar、依赖库和我的 java/kt 代码文件编译成库模块中的 dex。

我不熟悉直接在库模块上满足您的要求的方法。

作为解决方法,您可以:

  1. 在库(即使用com.android.library插件构建(模块中编写代码。
  2. 添加一个应用程序模块(即使用com.android.application插件构建,除了库模块之外没有任何源代码或依赖项(,它将用作库的包装器。
  3. 生成项目,并使用其生成的 dex 文件。

我创建了一个示例项目来说明这一点。 项目结构如下(我省略了不相关的文件(:

├── app  
│   ├── build.gradle  
│   └── src  
│       └── main  
│           └── AndroidManifest.xml  
└── testsdk  
├── build.gradle  
└── src  
   └── main  
      ├── AndroidManifest.xml  
       └── java  
           └── info  
               └── osom  
                   └── testsdk  
                       └── TestClass.java  

testsdk是一个库模块,app是一个库包装模块。TestClass.java是一个示例源文件,类似于库模块中包含的源文件。

两个AndroidManifest.xml文件都包含最低限度的功能,即app/src/main/AndroidManifest.xml内容是:

<manifest package="info.osom.q57441198"/>  

testsdkbuild.gradle文件包含一个示例依赖项,仅用于模拟库的依赖项。

apply plugin: 'com.android.library'  
android {  
compileSdkVersion 28  
}  
dependencies {  
implementation 'com.jakewharton.timber:timber:4.7.1'  
}  

包装器的(应用程序(模块build.gradle文件添加了对库模块的依赖:

apply plugin: 'com.android.application'  
android {  
compileSdkVersion 28  
defaultConfig {  
minSdkVersion 21  
}  
}  
dependencies {  
implementation project(':testsdk')  
}  

使用以下方法构建项目:
$ ./gradlew clean assembleRelease
然后在app/build/intermediates/dex/release/mergeDexRelease/out/classes.dex下找到生成的 dex 文件。

您可以使用 baksmali 来验证所有库源和库的依赖项是否捆绑在 dex 中:

$ baksmali classes.dex  
$ tree out  
out
├── info
│   └── osom
│       ├── q57441198
│       │   ├── BuildConfig.smali
│       │   └── R.smali
│       └── testsdk
│           ├── BuildConfig.smali
│           ├── R.smali
│           └── TestClass.smali
├── org
│   ├── intellij
│   │   └── lang
│   │       └── annotations
│   │           ├── Flow.smali
│   │           ├── // redacted...
│   │           └── Subst.smali
│   └── jetbrains
│       └── annotations
│           ├── Async$Execute.smali
│           ├── // redacted...
│           └── TestOnly.smali
└── timber
└── log
├── R.smali
├── Timber$1.smali
├── Timber$DebugTree.smali
├── Timber$Tree.smali
└── Timber.smali

包装器(应用程序(模块添加到 dex 文件的唯一开销是以下两个类:info/osom/q57441198/BuildConfig.smaliinfo/osom/q57441198/R.smali。你可以简单地忽略它们。如果您坚持删除它们,有一些工具可以帮助您。

最新更新