android studio generate aar with dependency

2020-02-14 02:53发布

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'])
}

2条回答
▲ chillily
2楼-- · 2020-02-14 02:58

What you're trying to do is not possible -- at least not possible in the way you have it described above.

查看更多
混吃等死
3楼-- · 2020-02-14 03:20

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: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!". 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

查看更多
登录 后发表回答