How to Optimize Your Android Apps (NDK) in Two Minutes on Intel® Architecture

Post Written By: Jean-Claude Cottier.

I’m Jean-Claude Cottier, a video game industry veteran. I’ve been working in this field for the last 18 years and in 2008, I’ve setup my own solo game studio: Ovogame. My games are available on a few platforms including Android: http://bit.ly/1i8aA1D. Recently, during an Intel CodeFest, I optimized all my games for  Intel Architecture and it was dead simple. I’ll describe my experience with the process and hopefully will get you interested to do the same.

To develop my games, I’m using my own technology: a C++ multi-platforms engine (Android, iOS, BB10, Win32 and OSX). I’m developing almost exclusively under Win32 with Visual Studio Express (for speed and ease of use purpose). To port my games to the other platforms, I simply need to copy the resources (source code and data) and recompile using the dedicated tools chain (ADT-NDK with Android, XCode for iOS and OSX...). Usually, it only takes a few minutes because everything is 100% compatible across all the different platforms. To reach this little miracle, my engine is only using standard C++ code and cross-platforms APIs (OpenGL, OpenAL, OpenSL…). For managing file format (jpeg, ogg, zip…), I’m using a different C/C++ library available with its source code so I can recompile on any platform. Obviously, I’m still using a bit of specific code for each platform (Java, Objective C, DirectX...), but I keep this code to a strict minimum and it never gets mixed with the game code.

When you develop natively for Android, the NDK is compiling your C++ code into a library that can be integrated in the Java project thanks to the JNI interface. In my engine, the Java code is kept to a bare bones minimum (mostly the communication with the system) and never changes from one game to the other. It’s now possible to create an Android application using only C++ (no Java), but I don’t recommend it because sometimes you’ll want to use third parties Java APIs (to display banner ads for example).

Nowadays, you can find different CPU powering Android devices (ARM, Intel x86…). This doesn’t matter for applications developed in Java because it’s an interpreted language. But when you are developing in C++ like myself, you have to compile your code for specific architectures. The majority of Android devices are powered by ARM chips. Like many C++ developers, I was only targeting ARM architectures (armv5 and armv7). Thanks to the NDK, you can compile your code for different architectures - armv5 for old Android devices and armv7 for newer ones. It’s automatically managed by the system - your APK is containing both versions and when your users launch your application, the most appropriate code will be used. Devices powered with x86 architecture can’t run ARM code obviously (as they are different architectures). By consequence, these devices must interpret ARM code via a virtual machine. Even if the x86 devices are doing an amazing job at interpreting ARM code, it’s a shame to not use their full capacity. If you compile your code for x86, your application will run faster on Intel devices and will consume less battery. Overall, it will be a better experience for your users. It’s very easy to support as you simply need to include a new compilation target. You need to open the jni/Application.mk in an editor and update the APP_ABI variable (it’s the one defining the different targets). As I was only targeting armv5 and armv7 before, my variable was set like this:

APP_ABI := armeabi armeabi-v7a

To add support to Intel architecture, you simply need to add x86 to the list.

 APP_ABI := armeabi armeabi-v7a x86

Now, every time you’ll compile your application, you’ll get an extra target compatible with x86 architecture that will be added to your APK. When the application is installed on an Intel based device, it’s this new compatible code that will be executed. All my games are now fully optimized for x86 devices. If like meyou are developing your applications in C++ with the NDK, you should also target for x86 architecture. It’s so simple, it would be a shame not to take advantage of it.

Personally, I didn’t face any technical problems supporting this new target as my engine is using standard C++. In fact, I’ve recompile and updated all my games the same day.

You need to know that the APK will be a tiny bit bigger (to store the x86 code) which can be annoying if you are close from the 50MB limit on Google Play.

If you are using  third party APIs only compiled for ARM, you won’t be able to use them anymore. I try to use only external libraries with the source code provided because it’s more cross-platform friendly.

If you need to change something in your makefile depending on the current architecture being compiled, you can edit your Android.mk and add conditions:

ifeq ($(TARGET_ARCH_ABI), x86)

‘This code will be visible only when compiling the x86 target.’

endif

If you want a more in depth article about porting your Android applications on x86, you could head to the Inte®l Developer Zone for Android website: http://intel.ly/1jnDfAd

I really think that for the vast majority of developers using the NDK like myself (with their own engine or Cocos2D for example), adding the word x86 in the APP_ABI variable will be enough to support Intel based devices. You will agree that this is largely possible within two minutes. You should do it.

Author Bio

Jean-Claude Cottier is a veteran developer who spent the last 18 years working in the game industry. He worked as an Engine Architect for Lionhead Studios and was lucky to create the 3D technology for some truly amazing games (Black & White and The Movies). Despite his
fascination for technology, Jean-Claude wanted to be more involved with game design. He left the AAA industry to setup Ovogame, his own indie company. He created a native cross platform engine witch allow him to port his numerous games on most relevant platforms in matter of minutes.