Why build an Android App from the command line?
For the purpose of creating a continuous integration build of an Android app, I needed to be able to build the app and its dependent modules from the command line. This is done using ant.
Prerequisites
Of course, you must have the appropriate Android SDK installed for your development platform. Make sure the tools
directory of the Android SDK is in your PATH
.
You’ll also want to install ant.
If you don’t already have Java installed, then maybe you should go visit the Android Developer site for some important background information.
Your Project
If you created your project using IntelliJ, then the build files mentioned below should be created for you automatically. If you created your project using Eclipse, then you’ll have to take an extra step to create the build files. Simply cd into the root directory of your project and execute the android
command to generate the build files:
$ cd android-project-directory
$ android update project --path .
This creates build.xml, default.properties, and local.properties for your project.
Important Files
There are four build files of critical importance which you can find in the root directory of your project:
build.xml
— this is the main ant build script. Check this file into your version control system.
default.properties
— has a huge warning that says it’s generated by the Android tools and should not be modified. Check this file into your version control system.
ant.properties
(optional) — allows you to add application-build-specific entries used by the build script. Typically empty for a straightforward Android app build but can be customized for non-standard directory structure or build dependencies. Check this file into your version control system or omit it entirely from the project if you have no customizations or build dependencies.
local.properties
— also generated by Android tools but should not be checked into your version control system. This is where the local path to your Android SDK directory root is specified, and this typically varies from one machine or build environment to the next.
Build Command
In order to build the app from the command line, cd to the root directory of your Android project (where the above files live and typically also where your src
directory and your AndroidManifest.xml
file live) and execute the ant command:
$ cd android-project-directory
$ ant clean debug
This command removes any leftover binaries or other artifacts from a previous build and rebuilds the app from scratch. If that is successful, then it packages and signs a debug version of the app. The console output from the command tells you where you can find the resulting .apk file for the app. Here’s an example of the console output from a successful build showing the location of the resulting .apk file:
$ ant clean debug
Buildfile: /Users/mharper/Development/Android/Demo/HelloCI/build.xml
[setup] Android SDK Tools Revision 10
[setup] Project Target: Android 2.2
[setup] API level: 8
[setup]
[setup] ------------------
[setup] Resolving library dependencies:
[setup] No library dependencies.
[setup]
[setup] ------------------
[setup]
[setup] WARNING: No minSdkVersion value set. Application will install on all Android versions.
[setup]
[setup] Importing rules file: tools/ant/main_rules.xml
clean:
[delete] Deleting directory /Users/mharper/Development/Android/Demo/HelloCI/bin
[delete] Deleting directory /Users/mharper/Development/Android/Demo/HelloCI/gen
...
compile:
[javac] Compiling 2 source files to /Users/mharper/Development/Android/Demo/HelloCI/bin/classes
...
debug:
[echo] Running zip align on final apk...
[echo] Debug Package: /Users/mharper/Development/Android/Demo/HelloCI/bin/HelloCI-debug.apk
BUILD SUCCESSFUL
Total time: 4 seconds
Building an App with Dependencies
It is common for an app to depend on one or more libraries that are built with a separate project. Thankfully, the Android build files make this easy to deal with.
Let’s say my HelloCI app depends on a HelloCILib that is a separate project built as an Android library. Let’s also say that the HelloCI and HelloCILib root directories are in the same directory:
$ ls
HelloCI HelloCILib
In order for the HelloCILib to be built before HelloCI, all you have to do is to reference its root directory path in the build.properties
file of the main project (HelloCI, in this case) thusly:
android.library.reference.1=../HelloCILib
You can add more dependent projects simply by bumping the number at the end of the property, e. g. android.library.reference.2 etc. I understand that you should not leave any gaps in the numbering, however.
Notice how the build looks slightly different now that the dependent library is included:
$ ant clean debug
Buildfile: /Users/mharper/Development/Android/Demo/HelloCI/build.xml
[setup] Android SDK Tools Revision 10
[setup] Project Target: Android 2.2
[setup] API level: 8
[setup]
[setup] ------------------
[setup] Resolving library dependencies:
[setup] /Users/mharper/Development/Android/Demo/HelloCI: ../HelloCILib => /Users/mharper/Development/Android/Demo/HelloCILib
[setup] ------------------
[setup] Ordered libraries:
[setup] /Users/mharper/Development/Android/Demo/HelloCILib
[setup] ------------------
[setup]
[setup] WARNING: No minSdkVersion value set. Application will install on all Android versions.
[setup]
[setup] Importing rules file: tools/ant/main_rules.xml
clean:
[delete] Deleting directory /Users/mharper/Development/Android/Demo/HelloCI/bin
[delete] Deleting directory /Users/mharper/Development/Android/Demo/HelloCI/gen
...
compile:
[javac] Compiling 4 source files to /Users/mharper/Development/Android/Demo/HelloCI/bin/classes
...
debug:
[echo] Running zip align on final apk...
[echo] Debug Package: /Users/mharper/Development/Android/Demo/HelloCI/bin/com.standalonecode.HelloCI-debug.apk
BUILD SUCCESSFUL
Total time: 4 seconds
Summary
Building an Android app from the command line is very straightforward, especially if you have a standard Android app directory structure. All of this work is leading up to creating a continuous integration build under Jenkins at cloudbees.com which is the subject of another blog post.
The source for this example can be found on GitHub.