Android NDK
While Java is the default programming language for Android, it isn’t always the best method for making apps, specifically games. Many engines used to make Android games use the Android Native Development Kit (NDK), because the NDK allows developers to write code in C/C++ that compiles to native code. This means that NDK games/apps can squeeze more performance out of devices. Here is your guide on how to use the Android NDK.

What is the Android NDK?

The Android Native Development Kit allows developers to get the most performance out of devices, this can be beneficial for game engines like Unity or Unreal Engine. Because the source code is compiled directly into machine code for the CPU (and not into an intermediate language like Java does) then developers are able to get the best performance. It is also possible to use other developers’ libraries or your own if there is something that you absolutely need to use.

How it works

cFileinAS
The “ndk-build” script is the heart of the Android NDK and it is responsible for automatically going through your project and determining what to build. The script is also responsible for generating binaries and copying those binaries to your app’s project path.

You have the ability to use the “native” keyword to tell the compiler that the implementation is native. An example is

public native int numbers(int x, int y);

There are also native shared libraries (.so) that the NDK builds from the native source code and Native static libraries (.a) which can be linked against other libraries. The Application Binary Interface (ABI) uses the .so files to know exactly how your app’s machine code will work with the system when the app is running. The NDK supports ARMABI by default along with MIPS and x86. More info on the ABI can be found here.

Everything works under an interface known as the Java Native Interface (JNI), this is how the Java and C/C++ components talk to each other. More information on the JNI can be found here.

If you are going to build using the ndk-build script, you will need to create two files, Android.mk and Application.mk. The Android.mk needs to go in your jni folder and defines the module plus its name, the build flags, which libraries to link, and what source files need to be compiled. Application.mk is also goes in the jni directory. It describes the native modules that your app requires.

How to install and use

NDKMainActivity
Installing the Android NDK is as easy as going to Preferences> Android SDK > Android NDK on OS X, and File>Settings>Android SDK>SDK Tools>NDK on Windows. Once installed, you will need to do a little more tweaking to get your app ready for NDK use. We will be starting with a new application as an example. You will need Android Studio 2.2 or higher to continue, make sure you have the latest version before you get started. Create a new project and select “Basic Activity” when prompted. Click the play button to run the app to make sure it works. Once everything is set up, let’s get everything ready for native development:

Go to preferences, or settings, depending on your operating system and click Build Tools>Gradle and select “Use default gradle wrapper (recommended)” if it is not already selected.

Find the latest experimental gradle plugin from here and note the version. Open your project’s, not module’s, build.gradle and replace classpath 'com.android.tools.build:gradle:2.1.0' with classpath 'com.android.tools.build:gradle-experimental:version number'
This will replace the stable version of Gradle with an experimental version with Android NDK support.

Go to your module’s build.gradle and replace the old code with this:

apply plugin: 'com.android.model.application'model {
  android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"
    defaultConfig {
      applicationId "com.example.abutt.aandk"
      minSdkVersion.apiLevel 22
      targetSdkVersion.apiLevel 23
      versionCode 1
      versionName "1.0"
    }
    buildTypes {
      release {
        minifyEnabled false
        proguardFiles.add(file('proguard-android.txt'))
      }
    }
    ndk {
      moduleName "hello-android-jni"
    }
  }
}
// others below this line: no change

Run the app and make sure everything is working and the app acts like it did before. Under the “buildTypes” block in the build.gradle for the module add:

  ndk {
    moduleName "hello-android-jni"
  }

In your app’s MainActivity.java, add this to the end of the program:

// new code
static {
  System.loadLibrary("hello-android-jni");
}
public native String getMsgFromJni();
  // new code done
} // class MainActivity

Run the program and make sure everything is still working as it should. Next up is to make the C/C++ file, you should notice that the getMsgFromJni() function is red, hover your mouse over the function until a red lightbulb pops up. Click the lightbulb and click the first option creating a function.

The C/C++ file will be under under a new folder called “jni”, open this file and paste this into the file:

#include <jni.h>JNIEXPORT jstring JNICALL
Java_com_example_abutt_aandk_MainActivity_getMsgFromJni(JNIEnv *env, jobject instance) {// TODO
return (*env)->NewStringUTF(env, "Hello From Jni! This was done in C!");
}

Make sure to change “com_example_abutt_aandk” to your app’s name. This file is read by the getMsgFromJni() function to display “Hello From Jni! This was done C!”.

Go back to your app’s MainActivity and add this to the end of the OnCreate() method:

((TextView) findViewById(R.id.jni_msgView)).setText(getMsgFromJni());

That’s it! Your app should run correctly and be utilizing the Android NDK! Now this isn’t a real world example on how the NDK would be used. A more real world example would be developing for OpenGL and Vulkan natively or using an engine like Unity or Unreal Engine that has the NDK built in.

Wrap Up

The Android NDK has some very specific use cases and probably shouldn’t be used in everyday development. But the NDK has given engine creators a great way to optimize their products for Android enabling great graphical capabilities while using less resources. Making a simple application using the Android NDK is not too difficult and with some practice native OpenGL is a real possibility. Do you use the Android NDK to develop with? Let us know in the comments below!