Getting Started with the Android NDK
The Android NDK (Native Development Kit), now on its seventh major revision, is a bundle of tools, libraries and documentation that can be used to link in native C/C++ libraries into your Android Java projects. It provides you with everything you need to link your own C/C++ libraries to your apps, as well as commonly-used system libraries like libc, libm, OpenGL ES, libz, JNI, and logging libraries for use.
In this tutorial, we explain why the NDK is important, when you should use it, and when you're better off without it.
Why Use the Android NDK?
There are two main reasons to consider using the Android NDK: performance and porting. For performance, the NDK can provide high-performance operations for your application if it's truly processor bound. That is, the application algorithms are tapping into all of the device's processing power within the DalvikVM; this code may see performance benefits from running natively.
But it's not like just any application would see performance benefits from using the NDK. There is some overhead from making the jump back and forth between the Android Java application and native code, not to mention the fact that using the Android NDK increases the code complexity of your project pretty substantially.
As for porting, you can use the NDK is to leverage existing code you've already got in C or C++. Here, using the NDK could simply your application development, allow for shared code with other platforms, and generally help you avoid maintaining parallel codebases in multiple programming languages. This perk is often leveraged with applications that target multiple operating systems using OpenGL ES.
Preliminary Android NDK Considerations
When you've decided the Android NDK is worth using for your project, you'll need to take your target device(s) and development machine OS into consideration before installing and using it. The NDK is not part of the stock Android SDK experience.
For device targeting, the Android NDK generates machine code for ARMv5TE, ARMv7-A, and x86. This provides coverage of all ARM-based Android devices as well as Intel-based devices, such as devices running on Intel Atom processors. However, this does not imply that all devices are supported. For one, the devices must support at least API Level 3. These days, that's not a particularly big issue (only 0.6% of devices are still only on Level 3, and Google no longer tracks levels below that). That said, Google TV devices do not support the NDK, despite many of them running API Level 12 now. Always test on device hardware to make sure your application behaves as expected.
As for the Android NDK prerequisites for your development machine, you can develop using the NDK on Windows, Mac, and Linux operating systems that support the Android SDK. On Windows, most functionality is available in NDK r7 (unlike previous versions) with one exception: ndk-gdb still requires the use of Cygwin.
Setting Up to Use the Android NDK
Unlike many other Android tools, the Android NDK can't be installed via the Android SDK Manager. Instead, the Android NDK package needs to be downloaded and installed on your development machine separately.
Begin by downloading the latest version of the NDK for your operating system from the Android site. At the time of this writing, the latest version was Android NDK, Revision 7 (Released November 2011).
After downloading the NDK, uncompress the file and extract the NDK source tree whenever you're storing your other developer tools. Then add that directory to your path. For example, we placed the NDK directory at d:\dev\tools\ndk.
Compiling NDK Apps
The NDK download comes with several sample apps. These demonstrate the two basic types of NDK usage. The first is a regular Java Android app that uses C code for only certain pieces of application functionality. If you're familiar with JNI (Java Native Interface), then you'll be accustomed to this type of scenario. The other way to use the NDK is to create a main Activity class implemented in C. The entire application can be written in C using this method. Compiling both types is no different.
Let's use two of the sample applications to compile and test your NDK installation.
- Import the projects into Eclipse by choosing New -> Android Project.
- Pick Create from existing source.
- Browse to your NDK directory, find the samples directory, and then choose the bitmap-plasma directory. You probably should rename the project name.
- Click the Next button and choose at least API Level 8.
- Repeat the above steps for the native-plasma sample app. We've used the project names Plasma and NativePlasma.
- Go to the command line and find the project directory for the Plasma sample app. In it, simply type
ndk-build. (You did put the NDK directory in your path, right? If not, we recommend doing so now.)
- Back in Eclipse, make sure the app is rebuilt by performing a Project, Clean operation.
You may notice in Eclipse that the apps both appear to be built successfully. This is not the case.
Repeat these steps for the NativePlasma app.
Now you're ready to run the two sample apps Plasma and NativePlasma on a device. Although their names are similar, their output is not identical. The NativePlasma app draws a single frame, full window plasma effect. The Plasma app animates a 200px by 200px area with a plasma effect. Your phone or tablet probably contains an ARM processor and so these examples will work.
But what if you try to load the app onto a device with an Intel Atom chip? It won't work by default. However, you can add x86 architecture to the build by either editing the Application.mk file and adding x86 at the end of the
APP_ABI line, or building with the "
ndk-build APP_ABI=all" command.
Want to run something more interesting? Load up and compile the project found in the san-angeles samples directory. It's a port of a small award-winning demo done several years back. Here's a video of it running on an ASUS Eee Pad Transformer Prime: