简体   繁体   English

android studio生成依赖的aar

[英]android studio generate aar with dependency

I have a library project(A) that reference another jar file(B.jar), but after generating aar file, jar file(B.jar) is not bundled in the output aar file, and when use this aar file, I got a NoClassDefFoundError . 我有一个库项目(A)引用另一个jar文件(B.jar),但是在生成aar文件之后,jar文件(B.jar)没有捆绑在输出aar文件中,当使用这个aar文件时,我得到了NoClassDefFoundError

Is there a way to make gradle bundle all dependency classes in the output aar file? 有没有办法让gradle捆绑输出aar文件中的所有依赖类? this is my build.gradle: 这是我的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? 有没有办法让gradle捆绑输出aar文件中的所有依赖类?

Yes, there is a way to do this, I have encountered this issue before. 是的,有办法做到这一点,我之前遇到过这个问题。 But this is going to be a long story, bear with me. 但这将是一个长篇故事,请耐心等待。

Background 背景

When you specify a dependency in build.gradle, you're telling Gradle to download an artifact (AAR / JAR) from Maven repository. 在build.gradle中指定依赖项时,您告诉Gradle从Maven存储库下载工件(AAR / JAR)。 So, Gradle need two things: 所以,Gradle需要两件事:

  1. The Maven repository location Maven存储库位置
  2. The Dependency itself 依赖本身

You specify Maven repository in top-level build.gradle 您可以在顶级build.gradle指定Maven存储库

repositories {
    jcenter()
    google()
}

and you specify the dependency on project-level build.gradle 并指定项目级build.gradle的依赖build.gradle

dependencies {
    compile 'com.example:mylibrary:1.0.1'
}

How does Gradle / Maven know that mylibrary requires other dependencies? Gradle / Maven如何知道mylibrary需要其他依赖? From your Dependency POM file . 从您的Dependency POM文件

POM Example POM示例

Let's use Square's OkHttp as an example, you can find this artifact in mvnrepository.com. 我们以Square的OkHttp为例,您可以在mvnrepository.com中找到这个工件。

OkHttp神器

OkHttp has a POM file. OkHttp有一个POM文件。 You can click that link to show the complete XML, I'm only showing you the interesting part which is the dependencies block. 您可以单击该链接以显示完整的XML,我只向您展示有趣的部分,即依赖性块。

<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 requires dependencies from other artifacts. OkHttp需要来自其他工件的依赖项。 Okio, Android, and jsr305. Okio,Android和jsr305。 But when you include OkHttp in your project you don't have to do include Okio, Android, and jsr305 on your project. 但是当您在项目中包含OkHttp时,您不必在项目中包含Okio,Android和jsr305。 Why is that? 这是为什么?

Because Gradle / Maven will look into POM files and download the dependencies for you. 因为Gradle / Maven会查看POM文件并为您下载依赖项。 No more NoClassDefFoundError . 没有更多NoClassDefFoundError

Your Library Project 你的图书馆计划

Back to your question, how to "combine" your library project into single .aar? 回到你的问题,如何将你的图书馆项目“组合”成单个.aar? Here are the steps: 以下是步骤:

  1. Publish your dependencies (your JAR or AAR) into Maven repository. 将依赖项(您的JAR或AAR)发布到Maven存储库中。

There is a big chance that your dependencies is already exist on mvnrepository, if it didn't exist you can submit your dependencies on bintray, mvnrepository, or host your own Maven repository. 您的依赖关系很可能已经存在于mvnrepository中,如果它不存在,您可以在bintray,mvnrepository上提交依赖关系,或托管您自己的Maven存储库。

  1. Create a POM file for you AAR. 为您创建一个POM文件AAR。

Just like in OkHttp dependencies block, you put your Library dependencies there. 就像在OkHttp依赖项块中一样,您将库依赖项放在那里。

  1. Submit your Library AAR to Maven repository. 将您的Library AAR提交到Maven存储库。

You can use mvndeploy to submit your library to Maven repository. 您可以使用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/"

If you don't want to do step 2 and 3 manually, as you can guess, "There is a gradle plugin for that!". 如果你不想手动执行第2步和第3步,你可以猜到,“有一个gradle插件!”。 The plugin is android-maven-publish , credit to: wupdigital to make these process easier. 该插件是android-maven-publish ,归功于:wupdigital使这些过程更容易。

Now you can use gradle command to publish your library: 现在您可以使用gradle命令发布您的库:

gradle yourlibrary:assembleRelease yourlibrary:publishMavenReleaseAarPublicationToMavenRepository

How to Share your Library Project 如何共享您的图书馆计划

Next time your teammate ask for your library, you can give them two things: 下次你的队友要求你的图书馆,你可以给他们两件事:

  1. Maven repository that contains your library and its dependencies Maven存储库,包含您的库及其依赖项
  2. Your library group, artifact, and version name 您的库组,工件和版本名称

That's it! 而已! No need to give your dependency dependencies to your peers. 无需将依赖项依赖项提供给您的同行。

Cheers 🥂 干杯🥂

你想要做的事情是不可能的 - 至少不可能像你上面描述的那样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM