我有一个库项目(A) 引用了另一个jar 文件(B.jar),但是在生成aar 文件后,jar 文件(B.jar) 没有 bundle 在输出的aar 文件中,当使用这个aar 文件时,我得到了一个 NoClassDefFoundError
。
有没有办法让gradle在输出的aar文件中 bundle 所有依赖类? 这是我的 build.gradle:
apply plugin: 'com.android.library'
repositories {
mavenCentral()
}
android {
buildTypes {
release {
runProguard true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile project(':common')
compile fileTree(dir: 'libs', include: ['*.jar'])
}
最佳答案
Is there a way to make gradle bundle all dependency classes in the output aar file?
是的,有办法做到这一点,我以前遇到过这个问题。但这将是一个很长的故事,请耐心等待。
背景
当您在 build.gradle 中指定依赖项时,您是在告诉 Gradle 从 Maven 存储库下载 Artifact (AAR/JAR)。所以,Gradle 需要两件事:
- Maven 存储库位置
- 依赖本身
您在顶级 build.gradle
中指定 Maven 存储库
repositories {
jcenter()
google()
}
并且你指定了对项目级build.gradle
dependencies {
compile 'com.example:mylibrary:1.0.1'
}
Gradle/Maven 如何知道 mylibrary
需要其他依赖项?来自您的依赖 POM file .
POM 示例
以Square的OkHttp为例,你可以在mvnrepository.com中找到这个神器。
OkHttp 有一个 POM 文件。您可以单击该链接以显示完整的 XML,我只向您展示有趣的部分,即依赖项 block 。
<project>
<modelVersion>4.0.0</modelVersion>
<parent>...</parent>
<artifactId>okhttp</artifactId>
<name>OkHttp</name>
<dependencies>
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
</dependency>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>...</build>
</project>
OkHttp 需要来自其他 Artifact 的依赖项。 Okio、Android 和 jsr305。但是,当您在项目中包含 OkHttp 时,您不必在项目中包含 Okio、Android 和 jsr305。这是为什么?
因为 Gradle/Maven 会查看 POM 文件并为您下载依赖项。不再有 NoClassDefFoundError
。
您的图书馆项目
回到您的问题,如何将您的库项目“组合”成单个 .aar?以下是步骤:
- 将您的依赖项(您的 JAR 或 AAR)发布到 Maven 存储库中。
您的依赖项很可能已经存在于 mvnrepository 上,如果它不存在,您可以在 bintray、mvnrepository 上提交依赖项,或者托管您自己的 Maven 存储库。
- 为您的 AAR 创建一个 POM 文件。
就像在 OkHttp 依赖 block 中一样,您将库依赖项放在那里。
- 将您的库 AAR 提交到 Maven 存储库。
您可以使用mvndeploy
将您的库提交到Maven 存储库。
mvn deploy:deploy-file \
-DgroupId=com.example \
-DartifactId=your-library \
-Dversion=1.0.1 \
-Dpackaging=aar \
-Dfile=your-library.aar \
-DpomFile=path-to-your-pom.xml \
-DgeneratePom=true \
-DupdateReleaseInfo=true \
-Durl="https://mavenUserName:mavenPassword@nexus.example.com/repository/maven-releases/"
如果您不想手动执行第 2 步和第 3 步,您可能会猜到,“有一个 gradle 插件可以做到这一点!”。插件是android-maven-publish , 感谢:wupdigital 使这些过程更容易。
现在您可以使用 gradle 命令发布您的库了:
gradle yourlibrary:assembleRelease yourlibrary:publishMavenReleaseAarPublicationToMavenRepository
如何分享您的图书馆项目
下次你的队友要你的图书馆时,你可以给他们两样东西:
- 包含您的库及其依赖项的 Maven 存储库
- 您的库组、 Artifact 和版本名称
就是这样!无需将您的依赖关系提供给您的同行。
干杯🥂
关于android studio 生成具有依赖性的 aar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26020466/