/ DevOps

Learn Gradle Episode 2

Last time, we explained something for the initialized script and this time we will learn more about Gradle for Android. Here are some resources list.

  • Android Developer website for Build System. In these pages, Android developer introduce the basic setting and script for build Android application.
  • The best resources are user guide from Gradle. Currently, the Gradle version is 2.11
  • Here is one public class from Udacity. It's can help you to learn more about how the Gradle build toll compiles and packages apps.

Build Process

Let's see more detail from scratch. The following picture will show you a clear mind for the whole android build process.
Android Build Process

Gradle help use to handle this build process. With Android Studio, we can just use IDE to build and release a new application, but know something deep is very helpful to know what has Gradle done exactly. We can building and running from command line. There are two build types for your application by default. One is debug, the other one is release. No matter which type you choose, you must sign your application before install the application to the device of emulator.

By using $./gradlew tasks you can see all tasks for your project. There are already a lot of tasks for help you build the application. Here, we use assembleDebug and assembleRelease to build the unsigned application. If you add new task in the build.gradle, it will also show in the list by using $./gradlew tasks.

Build signed application

Like mentioned above, unsigned application can't run on the device of emulator cause the security reason. How to tell Gradle to sign the unsigned application?

android {
    ...
    defaultConfig {
        ...
    }
    signingConfigs {
        release {
            storeFile file("your.keystore")
            storePassword "Password for key store"
            keyAlias "keyAlias"
            keyPassword "Password for alias")
        }
    }
    buildTypes {
        release {
            ...
            signingConfig signingConfigs.release
        }
    }
}

But this way, your password will be visible on the screen. There are two other ways can prevent this unsecured way.

  • Use system environment
 storePassword System.getenv("KSTOREPWD")
 keyPassword System.getenv("KEYPWD")

You can use export to set password

  • If you are using gradle command line, not some other shell script, you can use following
 storePassword System.console().readLine("\nKeystore password: ")
 keyPassword System.console().readLine("\nKey password: ")

It will ask for password on console while compiling.

More from Gradle

  • Gradle Wrapper

Gradle Wrapper can help us to use Gradle to compile very easy. Each Wrapper is tied to a specific version of Gradle, so when you first run one of the commands ./gradlew <task> for a given Gradle version, it will download the corresponding Gradle distribution and use it to execute the build. And the downloaded Gradle distribution is located $USER_HOME/.gradle/wrapper/dists.

  • Gradle Daemon

Gradle runs on the Java Virtual Machine (JVM) and uses several supporting libraries that require a non-trivial initialization time. As a result, it can sometimes seem a little slow to start. The solution to this problem is the Gradle Daemon: a long-lived background process that executes your builds much more quickly than would otherwise be the case.

By add org.gradle.daemon=true to your $USER_HOME/.gradle/gradle.properties. Next start build, daemon will hold on background.

gradle --stop. to stop it if you needed.

Build Environment

There are 3 ways to set build environment.

  • from gradle.properties in project build dir.
  • from gradle.properties in gradle user home.
  • from system properties, e.g. when -Dsome.property is set on the command line.

org.gradle.daemon We already introduce it above.

org.gradle.java.home This property is use to set JAVA_HOME if you have more than one jdk installed.

More properties please see here.

Copy task

Copy is a very simple task while compiling in your build process. We take a look at this task.

task brandCopy(type: Copy) {
    String brand = System.getenv('BRAND')
    String srcPath = String.format("src/%s/res", brand)
    FileTree tree =  fileTree(srcPath)
    tree.each {File file ->
        println file.absolutePath
    }
    from(tree)
    String desPath = "src/main/res"
    into(desPath)
    println "$brand copied"
}

At this task, we get the different brand resources and copy to src/main/res. And we print each file absolute path from the file tree.
By check ./gradlew -q tasks, we have brandCopy task in the task list. ./gradlew bandCopy will do the copy task directly.

More detail in Gradle will come in next eposide.