2

I have a android project with a single android library module, but I don't want to use it in a conventional way.

What I do right now is assemble the library (with the assemble gradle task) and post-process the resulting *.aar file.

I'd like to create a gradle task that:

  1. build the classes.jar and dexs it (similar to dex --dx ...);
  2. build the native libraries;
  3. move everything in a folder I can choose.

Unfortunately, I only found a way to just build the native libraries (with the embedded gradle task externalNativeBuildRelease).

Can anybody help me with this groovy gradle problem?

1 Answers1

2

Here's a build.gradle file that does most if not all of what you want extracted from this.
I used it in this answer.
Also see The Gradle build system- Tutorial and Writing Custom Tasks.

Here are the defined tasks:

  • task copyClasses
  • task assembleExternalJar
  • task copyJarToOutputs

It should give you the inspiration to do what you want:

import org.apache.tools.ant.taskdefs.condition.Os

//jrg
apply plugin: 'com.android.library'
//apply plugin: 'com.android.application'

android {
    compileSdkVersion Integer.parseInt(COMPILE_SDK)
    buildToolsVersion BUILD_TOOLS_VERSION

    defaultConfig {
        targetSdkVersion Integer.parseInt(TARGET_SDK)
        minSdkVersion Integer.parseInt(MIN_SDK)
    }
}
// Add the main project as a dependency for our library
dependencies {
    compile project(':app')
}
// Define some tasks which are used in the build process
task copyClasses(type: Copy) { // Copy the assembled *.class files for only the current namespace into a new directory
    // get directory for current namespace
    def namespacePath = PLUGIN_NAMESPACE.replaceAll("\\.","/")
    // set source and destination directories
    from "build/intermediates/classes/release/${namespacePath}/"
    into "build/intermediates/dex/${namespacePath}/"

    // exclude classes which don't have a corresponding entry in the source directory
    def remExt = { name -> name.lastIndexOf('.').with {it != -1 ? name[0..<it] : name} }
    eachFile {details ->
        def thisFile = new File("${projectDir}/src/main/java/${namespacePath}/", remExt(details.name)+".java")
        if (!(thisFile.exists())) {
            details.exclude()
        }
    }
}

task assembleExternalJar << {
    // Get the location of the Android SDK
    ext.androidSdkDir = System.env.ANDROID_HOME
    if(androidSdkDir == null) {
        Properties localProps = new Properties()
        localProps.load(new FileInputStream(file('local.properties')))
        ext.androidSdkDir = localProps['sdk.dir']
    }
    // Make sure no existing jar file exists as this will cause dx to fail
    new File("${buildDir}/intermediates/dex/${PLUGIN_NAMESPACE}.jar").delete();
    // Use command line dx utility to convert *.class files into classes.dex inside jar archive
    String cmdExt = Os.isFamily(Os.FAMILY_WINDOWS) ? '.bat' : ''
    exec {
        commandLine "${androidSdkDir}/build-tools/${BUILD_TOOLS_VERSION}/dx${cmdExt}", '--dex',
                    "--output=${buildDir}/intermediates/dex/${PLUGIN_NAMESPACE}.jar",
                    "${buildDir}/intermediates/dex/"
    }
    copyJarToOutputs.execute()
}

task copyJarToOutputs(type: Copy) {
    // Copy the built jar archive to the outputs folder
    from 'build/intermediates/dex/'
    into 'build/outputs/'
    include '*.jar'
}


// Set the dependencies of the build tasks so that assembleExternalJar does a complete build
copyClasses.dependsOn(assemble)
assembleExternalJar.dependsOn(copyClasses)
Jon Goodwin
  • 9,053
  • 5
  • 35
  • 54