From 99389fdf85c77f5d9b2eed4223b8a8b55f759b7e Mon Sep 17 00:00:00 2001 From: Lukacs Berki Date: Mon, 20 Jul 2015 08:36:28 +0000 Subject: Add an example Android app and a README.md file that details how to compile it. -- MOS_MIGRATED_REVID=98621744 --- examples/android/README.md | 35 +++++++++++++++++++++++++ examples/android/java/bazel/AndroidManifest.xml | 21 +++++++++++++++ examples/android/java/bazel/BUILD | 22 ++++++++++++++++ examples/android/java/bazel/Jni.java | 8 ++++++ examples/android/java/bazel/Lib.java | 10 +++++++ examples/android/java/bazel/MainActivity.java | 20 ++++++++++++++ examples/android/java/bazel/jni.cc | 23 ++++++++++++++++ 7 files changed, 139 insertions(+) create mode 100644 examples/android/README.md create mode 100644 examples/android/java/bazel/AndroidManifest.xml create mode 100644 examples/android/java/bazel/BUILD create mode 100644 examples/android/java/bazel/Jni.java create mode 100644 examples/android/java/bazel/Lib.java create mode 100644 examples/android/java/bazel/MainActivity.java create mode 100644 examples/android/java/bazel/jni.cc (limited to 'examples') diff --git a/examples/android/README.md b/examples/android/README.md new file mode 100644 index 0000000000..004d05f6ae --- /dev/null +++ b/examples/android/README.md @@ -0,0 +1,35 @@ +In order to build these examples, add the following two rules to the top-level `WORKSPACE` file (two directories above this file): + +```python +android_sdk_repository( + name="androidsdk", + path="", + api_level=21, + build_tools_version="21.1.1") +android_ndk_repository( + name="androidndk", + path="", + api_level=21) +``` + +Then the following command can be used to build the example app: + +``` +bazel build --android_crosstool_top=@androidndk//:toolchain //examples/android/java/bazel:hello_world +``` + +Yes, we know that this is a little clunky. We are working on the following things (and more): + * Eliminating the need for the `--android_crosstool_top` command line option + * Supporting other architectures than `armeabi-v7a` and compilers other than GCC 4.9 + * Eliminating the big ugly deprecation message from the console output of Bazel + +We also have a nice way to speed up the edit-compile-install development cycle for physical Android devices and emulators: Bazel knows what code changed since the last build, and can use this knowledge to install only the changed code to the device. This currently works with L devices and changes to Java code and Android resources. To try this out, take an `android_binary` rule and: + * Set the `proguard_specs` attribute to `[]` (the empty list) or just omit it altogether + * Set the `multidex` attribute to `native` + * Set the `dex_shards` attribute to a number between 2 and 200. This controls the size of chunks the code is split into. As this number is increased, compilation and installation becomes faster but app startup becomes slower. A good initial guess is 10. + * Connect your device over USB to your workstation and enable USB debugging on it + * Run `bazel mobile-install --android_crosstool_top=@androidndk//:toolchain ` + * Edit Java code or Android resources + * Run `blaze mobile-install --android_crosstool_top=@androidndk//:toolchain --incremental ` + +Note that if you change anything other than Java code or Android resources (C++ code or something on the device), you must omit the `--incremental` command line option. Yes, we know that this is also clunky and we are working on improving it. diff --git a/examples/android/java/bazel/AndroidManifest.xml b/examples/android/java/bazel/AndroidManifest.xml new file mode 100644 index 0000000000..3ad459c90b --- /dev/null +++ b/examples/android/java/bazel/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + diff --git a/examples/android/java/bazel/BUILD b/examples/android/java/bazel/BUILD new file mode 100644 index 0000000000..1a6ebe7e76 --- /dev/null +++ b/examples/android/java/bazel/BUILD @@ -0,0 +1,22 @@ +android_library( + name = "lib", + srcs = ["Lib.java"], +) + +android_binary( + name = "hello_world", + srcs = glob([ + "MainActivity.java", + "Jni.java", + ]), + manifest = "AndroidManifest.xml", + deps = [ + ":jni", + ":lib", + ], +) + +cc_library( + name = "jni", + srcs = ["jni.cc"], +) diff --git a/examples/android/java/bazel/Jni.java b/examples/android/java/bazel/Jni.java new file mode 100644 index 0000000000..5fa92e0baa --- /dev/null +++ b/examples/android/java/bazel/Jni.java @@ -0,0 +1,8 @@ +package bazel; + +/** + * JNI stubs for the Bazel Android "Hello, World" app. + */ +public class Jni { + public static native String hello(); +} diff --git a/examples/android/java/bazel/Lib.java b/examples/android/java/bazel/Lib.java new file mode 100644 index 0000000000..b2f27bf86d --- /dev/null +++ b/examples/android/java/bazel/Lib.java @@ -0,0 +1,10 @@ +package bazel; + +/** + * A tiny library for the Bazel Android "Hello, World" app. + */ +public class Lib { + public static String message() { + return "Hello Lib"; + } +} diff --git a/examples/android/java/bazel/MainActivity.java b/examples/android/java/bazel/MainActivity.java new file mode 100644 index 0000000000..c50cd4ac02 --- /dev/null +++ b/examples/android/java/bazel/MainActivity.java @@ -0,0 +1,20 @@ +package bazel; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; + +/** + * Main class for the Bazel Android "Hello, World" app. + */ +public class MainActivity extends Activity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Log.v("Bazel", "Hello, Android"); + Log.v("Bazel", "Lib says: " + Lib.message()); + System.loadLibrary("jni"); + Log.v("Bazel", "JNI says: " + Jni.hello()); + } +} diff --git a/examples/android/java/bazel/jni.cc b/examples/android/java/bazel/jni.cc new file mode 100644 index 0000000000..b103f45145 --- /dev/null +++ b/examples/android/java/bazel/jni.cc @@ -0,0 +1,23 @@ +#include +#include +#include + +const char* hello = "Hello JNI"; + +static jstring NewStringLatin1(JNIEnv *env, const char *str) { + int len = strlen(str); + jchar *str1; + str1 = reinterpret_cast(malloc(len * sizeof(jchar))); + + for (int i = 0; i < len ; i++) { + str1[i] = (unsigned char) str[i]; + } + jstring result = env->NewString(str1, len); + free(str1); + return result; +} + +extern "C" JNIEXPORT jstring JNICALL +Java_bazel_Jni_hello(JNIEnv *env, jclass clazz) { + return NewStringLatin1(env, hello); +} -- cgit v1.2.3