Last Updated: September 27, 2021
·
13.45K
· jonasvautherin

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