The sample Android app in this tutorial is a very simple application that makes an HTTP connection to the backend server and displays the resulting response.
Here, you'll do the following:
Let's take a look at the source files for the app. These are located in
The key files and directories are:
|Activity source file||
|Resource file directory||
Note that you're just looking at these files now to become familiar with the structure of the app. You don't have to edit any of the source files to complete this tutorial.
Bazel needs to run the Android SDK
and uses the SDK libraries to build the app. This means that you need to add
some information to your
WORKSPACE file so that Bazel knows where to find
them. Note that this step is not required when you build for other platforms.
For example, Bazel automatically detects the location of Java, C++ and
Objective-C compilers from settings in your environment.
Add the following lines to your
android_sdk_repository( name = "androidsdk", # Replace with your installed Android SDK API level api_level = 25 )
This will use the Android SDK specified referenced by the
environment variable, and automatically detect the latest build tools
version installed within that location.
Alternatively, you can explicitly specify the location of the Android
SDK and build tools version to use by including the
android_sdk_repository( name = "androidsdk", path = "/path/to/Android/sdk", api_level = 25, build_tools_version = "25.0.1" )
Optional: This is not required by this tutorial, but if you want to compile
native code into your Android app, you also need to download the
Android NDK and
tell Bazel where to find it by adding the following rule to your
android_ndk_repository( name = "androidndk", # Replace with the Android NDK API level api_level = 21 )
api_level is the version of the Android API the SDK and the NDK target
(for example, 19 for Android K and 21 for Android L). It's not necessary to set
the API levels to the same value for the SDK and NDK.
This web page
contains a map from Android releases to NDK-supported API levels.
android_sdk_repository, the path to the Android NDK is inferred from
ANDROID_NDK_HOME environment variable by default. The path can also be
explicitly specified with a
path attribute on
BUILD file is a text file that describes
the relationship between a set of build outputs -- for example, compiled
software libraries or executables -- and their dependencies. These dependencies
may be source files in your workspace or other build outputs.
BUILD files are
written in the Bazel build language.
BUILD files are part of concept in Bazel known as the package hierarchy.
The package hierarchy is a logical structure that overlays the directory
structure in your workspace. Each package is a
directory (and its subdirectories) that contains a related set of source files
BUILD file. The package also includes any subdirectories, excluding
those that contain their own
BUILD file. The package name is the name of the
directory where the
BUILD file is located.
Note that this package hierarchy is distinct from, but coexists with, the Java package hierarchy for your Android app.
For the simple Android app in this tutorial, we'll consider all the source files
$WORKSPACE/android/ to comprise a single Bazel package. A more complex
project may have many nested packages.
At a command-line prompt, open your new
BUILD file for editing:
BUILD file contains several different types of instructions for Bazel. The
most important type is the build rule, which tells
Bazel how to build an intermediate or final software output from a set of source
files or other dependencies.
Bazel provides two build rules,
android_binary, that you
can use to build an Android app. For this tutorial, you'll first use the
android_library rule to tell
Bazel how to build an
Android library module
from the app source code and resource files. Then you'll use the
android_binary rule to tell it how to build the Android application package.
Add the following to your
android_library( name = "activities", srcs = glob(["src/main/java/com/google/bazel/example/android/activities/*.java"]), custom_package = "com.google.bazel.example.android.activities", manifest = "src/main/java/com/google/bazel/example/android/activities/AndroidManifest.xml", resource_files = glob(["src/main/java/com/google/bazel/example/android/activities/res/**"]), )
As you can see, the
android_library build rule contains a set of attributes
that specify the information that Bazel needs to build a library module from the
source files. Note also that the name of the rule is
reference the rule using this name as a dependency in the
android_binary rule builds
the Android application package (
.apk file) for your app.
Add the following to your build file:
android_binary( name = "android", custom_package = "com.google.bazel.example.android", manifest = "src/main/java/com/google/bazel/example/android/AndroidManifest.xml", resource_files = glob(["src/main/java/com/google/bazel/example/android/res/**"]), deps = [":activities"], )
deps attribute references the output of the
activities rule you
added to the
BUILD file above. This means that, when Bazel builds the output
of this rule, it checks first to see if the output of the
rule has been built and is up-to-date. If not, it builds it and then uses that
output to build the application package file.
Now, save and close the file. You can compare your
BUILD file to the
master branch of the GitHub repo.
You use the
bazel command-line tool to run builds, execute
unit tests and perform other operations in Bazel. This tool is located in the
output subdirectory of the location where you installed Bazel. During
installation, you probably added this location to your
Before you build the sample app, make sure that your current working directory is inside your Bazel workspace:
Now, enter the following to build the sample app:
bazel build //android:android
build subcommand instructs Bazel to
build the target that follows. The target is specified as the name of a build
rule inside a
BUILD file, with along with the package path relative to
your workspace directory. Note that you can sometimes omit the package path
or target name, depending on your current working directory at the command
line and the name of the target. See Labels in
Bazel Concepts and Terminology page for more information about target labels
Bazel now launches and builds the sample app. During the build process, its output will appear similar to the following:
INFO: Found 1 target... Target //android:android up-to-date: bazel-bin/android/android_deploy.jar bazel-bin/android/android_unsigned.apk bazel-bin/android/android.apk INFO: Elapsed time: 7.237s, Critical Path: 5.81s
Bazel stores the outputs of both intermediate and final build operations in a set of per-user, per-workspace output directories. These directories are symlinked from the following locations:
$WORKSPACE/bazel-bin, which stores binary executables and other runnable build outputs
$WORKSPACE/bazel-genfiles, which stores intermediary source files that are generated by Bazel rules
$WORKSPACE/bazel-out, which stores other types of build outputs
Bazel stores the Android
.apk file generated using the
bazel-bin/android/ directory, where the subdirectory name
derived from the name of the Bazel package.
At a command prompt, list the contents of this directory and find the
You can now deploy the app to a connected Android device or emulator from the
command line using the
command. This command uses the Android Debug Bridge (
adb) to communicate with
the device. You must set up your device to use
adb following the instructions
Android Debug Bridge before
Enter the following:
bazel mobile-install //android:android
Note that the
mobile-install subcommand also supports the
flag that can be used to deploy only those parts of the app that have changed
since the last deployment.
Now that you've built a sample app for Android, it's time to do the same for the iOS app.