Getting started with Android NDK

You want to try out the Android NDK? I have gotten a lot of questions about how to setup and work with the NDK and I decided to write down how I do it. My goal with this entry is to gather all the information you need to get started with the Android NDK. I will not get into details about installing the basic components but will focus on setting up the environment. So you will need some knowledge about working with Android.

You will need to download and install a couple of things.


I usually go with the Eclipse Classic version. It is available from Installing Eclipse is simply just unpacking the downloaded file.

Android SDK

The SDK is located at There is a really good installation guide at

Android NDK

The NDK is located at with an installation guide.

Eclipse C/C++ Development Tools

To make it a bit easier we also install the C/C++ Development Tools to get C/C++ support in Eclipse. From the ‘Help’ menu choose ‘Install New Software…’

From the drop down select the update site for your eclipse version, in my case Indigo.

Under ‘Programming Languages’ you will find ‘C/C++ Development Tools’. Select it and click ‘next’ and follow the install instructions.

Getting started

I will show you how to get started by making a small application called NDKSetup.

Create a new android project for this example I will call it NDKSetup.

Project Wizard

First thing we need to do is to create a new folder called ‘jni’

The next thing we need to do is to setup Eclipse so we can build the JNI code. Click on the small down arrow on the external tool button and choose the ‘External Tools Configuration…’.

Mark the ‘Program’ and click on the ‘new’-icon.

Select a proper name.

Location is the location of the external tool you want to run, in our case the ndk-build file. Click on ‘Browse file system…’ and locate the ndk-build file located under your NDK folder.

The working directory is the jni folder we created in our project. Click on ‘Browse Workspace…’ …

… and choose the jni folder.

You should now have something looking like this:

Press run and you will get this error:

/Users/uncle/ndk-setup/android-ndk-r6b/build/core/ *** Android NDK: Aborting...    .  Stop.
Android NDK: Your APP_BUILD_SCRIPT points to an unknown file: /Users/uncle/Workspaces/ndk-setup/NDKSetup/jni/

This means two things. Your setup to the ndk-build works and you are missing the file.

Create a new file called in the jni folder.

In the file write this:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)


LOCAL_MODULE    := ndksetup
LOCAL_SRC_FILES := native.c


LOCAL_PATH := $(call my-dir)
An file must begin defining the LOCAL_PATH variable, this is where the source files are. The macro ‘my-dir’ is the path where the file is located.

include $(CLEAR_VARS)
Since all the building and parsing is done in the same context the variables called LOCAL_XXX is globals and need to be cleared.

LOCAL_MODULE := ndksetup
This is where you set the name used as the identifier for each module. Later used in java when loading the module. The system will add ‘lib’ before the module name when compiling into the .so file. So ndksetup will become The only exception is if you add ‘lib’ first in your module name then the system will not add it.

LOCAL_SRC_FILES := native.c
Here you add a list of the files you need to compile your module. You do not need to add headers or include files the system will take care of that for you.

The NDK provides you with two make files that parse and build everything accordingly to your file. The two once are BUILD_STATIC_LIBRARY for building static library and BUILD_SHARED_LIBRARY for building shared library.

For the example project here we use the BUILD_SHARED_LIBRARY.

If you run the external tool “NDK Build” we get a new error:

make: *** No rule to make target `/Users/uncle/Workspaces/ndk-setup/NDKSetup/jni/native.c', needed by `/Users/uncle/Workspaces/ndk-setup/NDKSetup/obj/local/armeabi/objs/ndksetup/native.o'.  Stop.

So lets att the missing native.c file into the jni folder.

Before we start adding code to the native.c file I think it is easier to write the API starting from java. We start by adding the loading of the library.

static {
    System.loadLibrary("ndksetup"); // ndksetup is the LOCAL_MODULE string.

We also need to define the function we are going to implement. By adding the keyword ‘native’ the system will know it is a function located in the native code.

private native void printLog(String logThis);

Putting in all together give us this:

package com.jayway.ndksetup;

import android.os.Bundle;

public class NDKSetupActivity extends Activity {

    static {

    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState) {

    private native void printLog(String logThis);

Back to the native.c file.

The name structure of the function is important. It is build from the java starting with a java identifier followed by the package name, followed by the class name, followed by the function name. This is one way of converting our java function into the native function. I usually do it by right clicking on the function name ( printLog ) and select ‘Copy Qualified Name’ paste it in the native.c file:


Start by changing all dots (.) to underscores (_).


Add the return value and a Java_ identifier to the function:

void Java_com_jayway_ndksetup_NDKSetupActivity_printLog(String)

The input variable is a String in java so lets make it a java string in native as well.

void Java_com_jayway_ndksetup_NDKSetupActivity_printLog(jstring logString)

The last thing we need to add is a reference to the JNI enviroment and a reference to java object that this function belongs to.

void Java_com_jayway_ndksetup_NDKSetupActivity_printLog(JNIEnv * env, jobject this, jstring logString)

Finally our first native function will look like this:


#define DEBUG_TAG "NDKSetupActivity"

void Java_com_jayway_ndksetup_NDKSetupActivity_printLog(JNIEnv * env, jobject this, jstring logString)
    jboolean isCopy;
    const char * szLogString = (*env)->GetStringUTFChars(env, logString, &isCopy);

    __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK: %s", szLogString);

    (*env)->ReleaseStringUTFChars(env, logString, szLogString);

Just for fun we add another function, a fibonacci function.

private native int fibonacci(int value);
jint Java_com_jayway_ndksetup_NDKSetupActivity_fibonacci(JNIEnv * env, jobject this, jint value)
	if (value <= 1) return value;
	return Java_com_jayway_ndksetup_NDKSetupActivity_fibonacci(env, this, value-1)
            + Java_com_jayway_ndksetup_NDKSetupActivity_fibonacci(env, this, value-2);

Now you are up and running with your NDK development for Android.

This Post Has 17 Comments

  1. Fry

    Thanks!! it works great !!

  2. Kiran

    Perfect. Really helped. Thanks a lot.

  3. Sharadchandra Pawar

    Your blog is very nice…
    It is very helpful.
    Thank You..

  4. Faniola Michel


    I need your help please. I need to use a static library that was developped by a third-party with NDK. Every time I try to integrate this library, I get errors. Could you please explain me how that could be done or give me a reference?

    Thank you very much in advance.

  5. ultramanjones

    Beautiful sir! More more! Bravo. Please make more tut’s on NDK. Pretty please with sugar on top! Rock on brother. Cheers!



  7. Vaishali

    Thanks..helped me…!!!

  8. Sayali

    Exception occurred executing command line.
    Cannot run program “E:say_androidandroid-ndk-r9cndk-build” (in directory “E:nativefirstjni”): CreateProcess error=193, %1 is not a valid Win32 application

  9. Enrico Br

    Thanks for this nice and useful tut! Thumbs up

  10. Vishal

    I get error 193 (%1 is not a valid Win32 app), when I run the app following these steps. What could be the reason?

  11. Niall

    I don’t even follow these steps and I get that win32 error. As a temporary solution I recommend not using Eclipse and instead building from the command line.

  12. Aleksandr

    It is brilliant! It is the best article about NDK.

  13. shailesh

    Thanks, It is a nice tut on NDK.

  14. shailesh

    One thing is there.
    when i add second function of fabanacci. It unable to compile.
    collect2: ld returned 1 exit status
    make: *** [D:/android/******/NdkSetup//obj/local/armeabi/] Error 1

  15. Andreas

    Really nice tutorial. Well explained without leaving out any steps. Thanks for that!!

  16. Renan Galdino

    Thanks from Brazil

Leave a Reply