Jni Tutorial for android

Vishwanath.M picture Vishwanath.M · Apr 14, 2011 · Viewed 56k times · Source

Hi, can anyone suggest me some good resources to learn JNI for Android and some good JNI Tutorials?

Answer

Hayk Nahapetyan picture Hayk Nahapetyan · Nov 15, 2012

Tutorial for ECLIPSE

Here is first and second small tutorials, but if you want to write a simple program that uses JNI , you may continue reading :)

Create Android application project , Once your project has been created, you’ll need to create a new folder inside the top level of the project. To do this right click on your project name → New → Folder. Name this folder jni. Than add class with name SquaredWrapper. add these code in it

package org.edwards_research.demo.jni;

public class SquaredWrapper {
    // Declare native method (and make it public to expose it directly)
    public static native int squared(int base);

    // Provide additional functionality, that "extends" the native method
    public static int to4(int base)
    {
        int sq = squared(base);
        return squared(sq);
    }

    // Load library
    static {
        System.loadLibrary("square");
    }
} 

Open terminal. You must compile these code for getting header file. At first call this command.

cd src # change into the source directory
javac -d /tmp/ org/edwards_research/demo/jni/SquaredWrapper.java

Than

cd /tmp
javah -jni org.edwards_research.demo.jni.SquaredWrapper

SO you'll have header file named org.edwards_research.demo.jni.SquaredWrapper in your tmp directory.

it must be something like this

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_edwards_research_demo_jni_SquaredWrapper */

#ifndef _Included_org_edwards_research_demo_jni_SquaredWrapper
#define _Included_org_edwards_research_demo_jni_SquaredWrapper
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     org_edwards_research_demo_jni_SquaredWrapper
 * Method:    squared
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_org_edwards_1research_demo_jni_SquaredWrapper_squared
  (JNIEnv *, jclass, jint);

#ifdef __cplusplus
}
#endif
#endif

change these name for some short one for your comfort, for example square.h. Copy this header file in the jni folder of your app. Than create square.c file in same folder, copy this in it.

 #include "square.h"

JNIEXPORT jint JNICALL Java_com_example_android_1jni_1second_1demo_SquaredWrapper_squared
      (JNIEnv * je, jclass jc, jint base)
    {
            return (base*base);
    }

Add this in your MainActivity.java

int x = SquaredWrapper.to4(2);
        x = x*2;

Add Android.mk file in jni folder with this body

    LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := squared
LOCAL_SRC_FILES := square.c

include $(BUILD_SHARED_LIBRARY)

It must create library from header and cpp files.

So you have only to do some configurations by looking on my first link Now you can compile it , be sure that your library has created and your lib directory consist it.

Tutorial for Android Studio

Let's consider you have simple android application opened by Android Studio

step 1: open Your application by Android Studio

step 2: Download NDK and set the path to NDK in local properties of your application(below/above of android sdk path) like this ndk.dir=C\:\\Android\\android-ndk-r10e

P.S. for windows double // , for linux one /

step3: Add JNI folder in the app (right click on the app -> new -> folder -> JNI Folder)

step 4 Set up the Gradle by this way:

Add this code in app/build.gradle for starting NDK

   sourceSets.main {
        jni.srcDirs = []
        jniLibs.srcDir 'src/main/libs'
    }

    tasks.withType(NdkCompile) { // disable automatic ndk-build call
    compileTask -> compileTask.enabled = false
    }

    task ndkBuild(type: Exec) { // call ndk-build(.cmd) script
        if (Os.isFamily(Os.FAMILY_WINDOWS)) {
            commandLine 'cmd', '/c', 'ndk-build.cmd', '-C', file('src/main').absolutePath
        } else {
            commandLine 'ndk-build', '-C', file('src/main').absolutePath
        }

   tasks.withType(JavaCompile) {
        compileTask -> compileTask.dependsOn ndkBuild
    }

step 4:

Create files Android.mk and Application.mk in JNI folder of the app with this bodies:

Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := main
LOCAL_SRC_FILES := main.cpp

include $(BUILD_SHARED_LIBRARY)

Application.mk

APP_ABI := all
include $(BUILD_SHARED_LIBRARY)

In APP_ABI you choose which compilers to use. It

step 5:

We have to manually run NDK as we disable it from build.config. For creating com_example_nativedemo_app_MainActivit.h file in src\main\jn folder we have to run this command in terminal

javah -d .\jni -classpath C:\Intel\INDE\IDEintegration\android-sdk-windows\platforms\android-21\android.jar;..\..\build\intermediates\classes\debug com.example.mydemo.nativedemo.MainActivity

for windows cmd you have to give the full path of files. For

step 6:

Add file main.cpp in JNI folder with this body:

#include <string.h>
#include <jni.h>
#include <vchat_cpptest_Hellojnicpp.h>

extern "C" {
      JNIEXPORT jstring JNICALL
      Java_vchat_cpptest_Hellojnicpp_stringFromJNI
      (JNIEnv *env, jobject obj)
      {
            #ifdef __INTEL_COMPILER_UPDATE
              return env->NewStringUTF("Hello from Intel C++ over JNI!");
          #else
              return env->NewStringUTF("Hello from default C++ over JNI!");
          #endif
}