This is the latest post in a series by Charles Wilde about porting an app containing extensive C++ code to Android. The other posts are listed at the end of this one.
I am working on a port of a large mobile app from Windows Mobile to Android. The app (Aton Connect) comprises about 100,000 lines of C++ code and another 40,000 lines of C# code which I am converting to Java for operation on Android.
At the time I began this effort, the Android NDK was a few weeks away from its initial release. Although developing C++ shared libraries for Android was possible, it was a very convoluted effort. I documented those efforts in my previous posts in this series.
Since then, much progress has been made on the NDK, both by the Google Android team and by third party open source projects. One of the most common searches on this website concerns the Android development environment. Many of you are looking for a set of Android software development tools that approximate the ease of use of Visual Studio.
We are much closer to that now with a tool developed by the Eclipse Sequoyah project. This project’s goal is to integrate a variety of open source tools in one location to assist mobile developers. They have recently added a new tool called “Sequoyah Android Native Code Support”.
The main Eclipse distribution provides support for native C++ code via a set up plugins labeled “CDT”. With CDT, you can, for example, create shared libraries written in C++ for use with Java programs using JNI as the interface glue. For use with Linux desktop apps, this works quite well, with the ability to work with the source code in an IDE instead of using a collection of command line tools like make and GDB.
How to Debug the JNI Glue Code
I used these plugins in the initial phases of porting the large body of C++ code from Windows to Linux and they worked quite well. One major hurdle was determining how to debug the JNI glue code. This is C/C++ code that makes extensive calls to the JNI API library to marshal data and execution bi-directionally between a native shared library and the Java main application. The JNI code is amazingly complex low level coding where mistakes are easy to make. Good debugging tools for JNI are essential.
The solution was to create a simple Java application to exercise all of the native shared library interfaces. I used a small set of elements from the Java SWT GUI libraries to provide the minimum functionality needed to test the native shared libraries. There is no direct mapping between the Java GUI libraries such as SWT and Swing with the GUI of the Android platform. I would need to recreate the Java test application when moving to actual testing on the Android emulator.
Debugging with this arrangement was still challenging, because starting the Java app in the Eclipse debugger would not activate a breakpoint in the C++ code. I resolved this by building a small C++ test harness that uses the “JNI_CreateJavaVM” JNI API function to start a Java VM which in turn starts the Java test application which then calls the C++ shared libraries. By starting the debug process in the C++ test harness, one can place breakpoints in the JNI glue code also written in C++. With this arrangement you can use Eclipse to debug the Java code by starting the debugger on the Java test application. Alternately, you can debug the C/C++ native code, including the JNI code, by starting the debugger on the C++ test harness.
After debugging as much code as possible in the Linux desktop environment, it was time to move to the Android emulator environment. The Java test application needs to be adjusted to use the Android Java GUI libraries, which are similar in architecture to the SWT libraries, although with significant differences in implementation details. After installing the Android SDK, building and debugging Java code is straightforward, and can be accomplished through the Eclipse IDE.
The Android NDK for C/C++ code is another matter entirely. As provided by the Android team, one must rely on command line building and debugging of the native code. If you are used to working with IDE tools, this is quite a step back in productivity. The Eclipse CDT cannot be used as delivered for working with Android C++ shared libraries, because the CDT desktop tool chain must be replaced with a cross platform tool chain included in the NDK. In addition, the Android NDK includes custom build scripts to simplify the build process using the command line. These custom build scripts such as Android.mk and ndk-build need to replace the traditional make files used by CDT.
Eclipse Sequoyah to the Rescue
This is where the Eclipse Sequoyah project comes to the rescue. With one click of the mouse, Sequoyah will install a large range of changes into an Eclipse Android SDK project to give simultaneous support to the NDK. The changes include incorporating the cross platform tool chain, arranging for C++ debugging through the GDB server located in the Android device or emulator, making use of the NDK custom build scripts, generating shared libraries in a location where they get automatically incorporated into the Java build, adding to the project folder structure, and more.
I am still working through the details of the Sequoyah Android Native Code Support package. The package promises seamless single stepping from Java code into JNI code. I have not got that debugging part working yet, but the other features of the Sequoyah Android Native Code Support package that I have verified make it well worth the time it takes for integration.
As with many open source projects, the Sequoyah documentation is a bit slim, but sufficient to get you started. The Sequoyah Android Native Code Support was added to the package at the version 1.1 level. Instruction for adding this tool to Eclipse is located here: http://www.eclipse.org/sequoyah/downloads/index.php#latest.
Be sure to uncheck the “Group items by category” option so you can see the desired item: Sequoyah Android Native Code Support. There is a description of using Sequoyah to debug Android native shared libraries here: http://www.eclipse.org/sequoyah/documentation/native_debug.php.
I would like to hear about your experiences with Sequoyah.
* * * * * * *
Other posts in this series:
- Developing An Android Mobile Application
- Android Software Development Tools – What Do I Need?
- Android Native Development on Ubuntu 9.04 (Jaunty Jackalope)
- Android Native Development Using the Android Open Source Project
- Android Native Libraries for Java Applications
- Porting Native Code to Android: From Business Case to Coding
- Pure Native App or Java Shell for Android Market?
- Porting Applications Using the Android NDK
- Integrating the Android NDK C++ Native Support into Eclipse Using Sequoyah
With 20+ years as a top software and firmware developer, Charles Wilde has acquired a combination of proven business smarts, mobile development skills and device engineering expertise that is hard to match. Charles is available to consult with you and your team about native code development in Android, Windows Mobile or Windows CE. Wilde is the author of Porting Native Code to Android and can be reached at AtonMail ( at) aton (dot) com. © 2010 Aton International, Inc.