Today I bought an Android powered tablet, the Acer Iconia 7" tablet. As my friends keep telling me, I should start doing Android development, so that I can port the little crane that could to Android devices. Apart from the horrible colours and contrast of the display, I am satisfied with the device so far. Graphics performance seems way behind what an iPad2 can do though, so graphics optimizations are going to be important. Here are some things I learned about Android programming so far:
- You need to install an SDK and an NDK.
- As of recently, you can do native development in C without writing a single line of Java code. To do this, see the NativeActivity sample from the NDK.
- You can do development from the command line without IDE's.
- Instead of make, you need to use a combination of ndk-build and ant.
- GLESv1_CM is the OpenGL ES1 library to use. CM stands for COMMON and means that it uses floating point, not fixed point.
- Doing 'ant debug' and 'ant installd' is often not enough, as I need to do a clean before building. Are the dependencies not set up properly in the sample projects?
- The emulator cannot do OpenGL ES2, only ES1. When doing ES1 it is super slow, even on a modern mac.
- The equivalent of GLX for Android is called EGL
- Android NDK by default targets the ARMV6 devices, which means software floating point emulation. This is very slow.
- To target ARMV7 with hardware floating point (VFP), add this to jni/Application.mk: APP_ABI := armeabi-v7a
- To see verbose output of the build process, use ndk-build V=1
- Loading assets from native code is a painful experience. So instead I convert images to C source code, and build as a shared object. Then I use dlopen() to get to the data.
- To debug simply run ndk-gdb --start from the project dir.
- You can set java compiler flags on the ant command line like this: ant "-Djava.compilerargs=-Xlint:unchecked -Xlint:deprecation" debug
- You can make screenshots with the ddms utility. Select the device and press ⌘S to grab the screen.
- To incorporate a third party framework, all you have to do is copy the .jar file into your projects ./lib/ directory, and the build system will automagically find and use it.
- If you want to install certain resource types without compression, then you need to edit your SDK. Change the tools/ant/build.xml file by adding a < nocompress extension="foo" /> to the aapt section.
- Don't get confused by -msoft-float and -mhard-float, they do not toggle the hardware floating point unit. Instead they influence the convention for passing function arguments. So using -mhard-float will only get a modest speed bump, at the cost of decreased ABI compatibility.
- in jni/Application.mk you need to keep APP_PLATFORM set to android-20 or lower. At android-21, downward compatibility breaks, and on a pre-android L device, your app will crash with a 'failed: dlopen failed: cannot locate symbol "rand" referenced by...' error.
I am using The Android NDK Beginner's Guide as reference, as well as a guide by IIvan Vučica. That last one is pretty ambitious: it sets up the development environment so that you can do Objective C for Android. However, I decided to keep it simple, and do my project in C.
There is an excellent GDC presentation from Lars Bishop of nVidia on android development.
For future reference, you need to set up some environment variables. This is what I use in my .bashrc file:
export ANDROID_NDK_ROOT=$HOME/android-ndk-r9d export ANDROID_SDK_ROOT=$HOME/android-sdk-linux export NDK_MODULE_PATH=$HOME/apps:$HOME/src PATH=$PATH:$ANDROID_NDK_ROOT:$ANDROID_SDK_ROOT