Native Android Development Part 1


I’ve ben spending the wee hours trying to grok native development on Android. NowI plan to spend my remaining hours trying to figure out what the difference between a “wee hour” and a regular hour is. I mean, c’mon… where does one find a “wee hour”? Is it a unit of time tracked by those under age 6 or those of diminutive stature? Am I being a baby just for bringing up this confusing point? I digress. I’m Cliff. You’re here because you’ve also spent some of your wee hours trying to understand the NDK, which is likely another black art. I’m here because I’m slowly understanding more pieces of it each day and have finally grown comfortable enough with what I know to attempt to share knowledge with you. Welcome to my world. Don’t get excited over the title, I don’t plan on making this into a series or anything. Any further articles which are consecutively numbered and related are by pure coincidence and not planned.

NDK Unit Testing

This week I am trying to tackle unit testing with the NDK. (Check back later for tips on how to build NDK apps with Gradle in Android studio!) For those who don’t know, the Android NDK ships with a number of unadvertised and hidden gems. Among those are docs, sources, samples, and a C++ unit test framework named GoogleTest. Some of you may recognize GoogleTest from other projects. I tripped over it while scouring the web looking for a suitable testing library for C/C++ and later discovered that not only can you download it from Google and build it for Android, but that it is now included with the latest NDK tools. Before I get distracted or sign off let me include the following tidbit (feel free to skip to the next bolded section since I haven’t explained the details yet):

IMPORTANT TO KNOW BEFORE I FORGET TO TELL YOU!!!
If you are building GoogleTest, or guest as the fellas on the street call it, make sure you link to a C runtime that includes STL. More specifically, put something like this in your Application.mk:

APP_STL := stlport_static

If you’re doing something advanced, like using more than one native library in your app then you might want to read deeper and understand what it means to static link an STL runtime to your app. It might make sense to link the runtime dynamically instead because if you link more than one STL you get, like, in lots of trouble and stuff. So your code might want to look like this instead:

APP_STL := stlport_static

Lastly, if you are building either gtest or your native library with a non-standard structure you will need to point “ndk-build” to your Application.mk file that includes the above magic code. There is a command line flag to tell “ndk-build” where to find it.

ndk-build NDK_APPLICATION_MK=path/to/Application.mk

If you don’t understand any of the above just hold tight and I’ll eventually explain it all later on. Just know that this is something that you will need to do at some point.

Running CPP Unit tests without an apk
I am excited about this feature because, to date, I have been testing my JNI code through Java using the Android JUnit framework. GoogleTest allows you to run CPP unit tests against a .so native library without bundling it with a “.apk” and without the overhead of calling into it from Java. It makes tests run faster, it allows for quicker development of tests, and overall speeds everything up by removing a layer from each iteration. The quickest way to see all of this work is to follow the tutorial below which uses Google’s only sample code.

Copy the framework and samples from ${NDK_HOME}/sources/third_party into any folder of your choosing.
Create an Application.mk file which links in STL support as a static library. Use the something like the following:

APP_PLATFORM := android-9
APP_STL := stlport_static
APP_CPPFLAGS := -fno-rtti
NDK_TOOLCHAIN_VERSION=4.6

Build all source using the NDK:

~/android-ndk-r9d/ndk-build NDK_PROJECT_PATH=./ APP_BUILD_SCRIPT=./Android.mk NDK_APPLICATION_MK=./Application.mk

This should generate a bunch of executables and one .so under libs/armeabi/ which need to be pushed to the device. Push them to the device using the following:

for eachFile in `ls libs/armeabi/`; do adb push libs/armeabi/$eachFile /data/local/tmp; done

Run all of the tests on your device

adb shell "LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/gtest_all_test"

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s