Android NDK / JNI Quickstart
This is a tutorial about creating a "Hello World" project on Android using the NDK. It assumes that you are using Eclipse-ADT (from Google). It is not meant to detail how JNI works but only to give an example.
Create a new Android project in Eclipse-ADT
Create a folder called "jni" in the project (at the same level as "src" or "res"). This folder will contain all of the C/C++ files
-
Create "jni/Android.mk" with the following content. It is actually the makefile used by android to compile your native code
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := helloJNI LOCAL_LDLIBS := -llog include $(BUILD_SHARED_LIBRARY)
-
(Optional, but required for instance with OpenCV): Create "jni/Application.mk" with the following content:
APP_STL := gnustl_static APP_CPPFLAGS := -frtti -fexceptions APP_ABI := all
-
In your Activity (Java file), include the C++ library you gonna create
public class MainActivity extends Activity { static { System.loadLibrary("helloJNI"); } […]
-
Declare a native prototype that will be used to call the corresponding C/C++ function in the library "helloJNI", such as:
private native void debugMessage();
-
Actually call this function from Java your code, for instance:
@Override protected void onResume() { super.onResume(); debugMessage(); }
-
Create the JNI "glue" between the Java code and its C/C++ equivalence:
- Go to <your_project>/bin/classes
- Run the following command: javah -o ../../jni/mainActivity.h com.example.hellojni.MainActivity
You now have a new file - mainActivity.h - in <your_project>/jni (you may need to refresh in Eclipse).
-
Create <yourproject>/jni/mainActivity.cpp (NOTE: prototypes are already generated in mainActivity.h by javah_)
#include "mainActivity.h" #include <android/log.h> //============================== // Declarations //============================== #define LOG_TAG "mainActivity.cpp" #define DPRINTF(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) #define IPRINTF(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) #define EPRINTF(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) JNIEXPORT void JNICALL JNICALL Java_com_example_hellojni_MainActivity_debugMessage (JNIEnv *, jobject) { DPRINTF( "%s\n", __FUNCTION__ ); DPRINTF( "This is a debug message coming from my C++ code!\n"); }
-
Add the new cpp file you created to Android.mk:
LOCAL_SRC_FILES := mainActivity.cpp
-
Android.mk now looks like:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := helloJNI LOCAL_SRC_FILES := mainActivity.cpp LOCAL_LDLIBS := -llog include $(BUILD_SHARED_LIBRARY)
Add C/C++ Nature to your project:
Right Click on your project > Android Tools > Add Native Support…Run your application