Generating Android apklibs with Gradle (Tutorial)

So, you've decided to switch your Android library project to the new hotness (Gradle, Android's new build system)? About to release a new Android library? Read on.

1. What is apklib?
apklib is a way to bundle an Android library project.

Many Android developers thought the existing Android build system, based on Ant, was insufficient. Maven is arguably a better build system, so the android-maven-plugin was created, to let Maven users build their Android projects.

Maven downloads all of the dependencies for your project - for most Java projects, these are jars. The apklib format was invented as a way to share Android code+resources. It’s essentially a zipped up Android library project, which was already the status quo for code+resource sharing.

2. Why doesn’t Gradle support it?
The Android team introduced the aar format at Google I/O 2013. From what I gather, it differs from apklib in one major way: classes are compiled and included in a classes.jar in the root of the aar, whereas apklib cannot contain compiled class files or jars (they are ignored).

3. Why doesn’t the android-maven-plugin support aar?
I suppose they haven’t got around to it yet. Plus, apklib came first! Ask +Manfred Moser :-)

4. Show me the code
(you can see a complete example here: https://github.com/googlemaps/android-maps-utils/blob/master/library/build.gradle

So, if you want to ship an apklib to keep your Maven users happy, you’ll need to generate it and upload from your Gradle build script. I suppose someone will one day release a Gradle plugin, but for now the build rules are simple:

task apklib(type: Zip) {
    appendix = extension = 'apklib'

    from 'AndroidManifest.xml'
    into('res') {
        from 'res'
    }
    into('src') {
        from 'src'
    }
}

You may need to tweak this a bit (different paths for source code, resources, etc). You will then want to declare your apklib as an artifact of your project:

artifacts {
    archives apklib
}

5. Uploading to Maven
Deploying multiple artifacts to Maven is a bit tricky. If you’re using the maven plugin from Gradle, you’ll need to modify your mavenDeployer entry:

addFilter('aar') { artifact, file ->
    artifact.name == archivesBaseName
}
addFilter('apklib') { artifact, file ->
    artifact.name == archivesBaseName + '-apklib'
}

You’ll end up with two artifacts, yourproject and yourproject-apklib. You may want to inverse these (yourproject and yourproject-aar), if you already have people depending on the apklib packaging with the existing name.

#androiddev #gradle  
34
41
J. Eric Sepulvado's profile photoQuang-Hai PHAN's profile photoPrateek Srivastava's profile photoThomas Bruyelle's profile photo
5 comments
 
Is it just me, or is every other DevRel team throwing their weight behind Android nowadays (we are too)?
 
+Ikai Lan Well, the Maps team owns the Maps Android API, so it's natural that the Maps DevRel team works on it too :-)
 
Thanks Thomas, I fixed it. Existing re-shares won't have the update, though.
 
Could you let me know what task were you using to upload the archives? Using `./gradlew uploadArchives` just uploads the apklibs for me. I can see an .aar produced in build/libs and in build/exploded-bundles
Add a comment...