Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

gradle - 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.

Is there a way to make gradle bundle all dependency classes in the output aar file? this is my 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'])
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Is there a way to make gradle bundle all dependency classes in the output aar file?

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. So, Gradle need two things:

  1. The Maven repository location
  2. The Dependency itself

You specify Maven repository in top-level build.gradle

repositories {
    jcenter()
    google()
}

and you specify the dependency on project-level build.gradle

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

How does Gradle / Maven know that mylibrary requires other dependencies? From your Dependency POM file.

POM Example

Let's use Square's OkHttp as an example, you can find this artifact in mvnrepository.com.

OkHttp Artifact

OkHttp has a POM file. You can click that link to show the complete XML, I'm only showing you the interesting part which is the dependencies 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 requires dependencies from other artifacts. Okio, Android, and jsr305. But when you include OkHttp in your project you don't have to do include Okio, Android, and jsr305 on your project. Why is that?

Because Gradle / Maven will look into POM files and download the dependencies for you. No more NoClassDefFoundError.

Your Library Project

Back to your question, how to "combine" your library project into single .aar? Here are the steps:

  1. Publish your dependencies (your JAR or AAR) into Maven repository.

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.

  1. Create a POM file for you AAR.

Just like in OkHttp dependencies block, you put your Library dependencies there.

  1. Submit your Library AAR to Maven repository.

You can use mvndeploy to submit your library to Maven repository.

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:[email protected]/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!". The plugin is android-maven-publish, credit to: wupdigital to make these process easier.

Now you can use gradle command to publish your library:

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
  2. Your library group, artifact, and version name

That's it! No need to give your dependency dependencies to your peers.

Cheers ??


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...