Implement jni in Android Studio ProjectLast updated: 2019-06-01

What is Java Native Interface?

JNI stands for Java Native Interface is an interface developed for interaction between bytecode that android compiles from managed code(java/kotlin) with native code(written in c/c++)

Compiler

While you can create application entirely in java, there must be some situation in which something cant be achieved using java. So programmers will use the JNI to write java native method to handle those siutation when an application cannot be written entirely in java

JavaVM and JNIEnv

JNI defines two Key Data Structures, JavaVM and JNIEnv. The JavaVM will provide the invocation interface function which will allow us to create and destroy a javaVM. Usually we can have multiple javaVMs per process but in android it is allowed as one. JNIEnv provides most of the JNI functions. The native function will receive the JNIEnv as the first arguments. The JNIEnv is used for thread-local storage. This is the reason a JNIEnv cannot be shared between threads. If a piece of code has no otherway to pass get its JNIEnv, we have to share the javaVM and use the GetEnv to discover the thread's JNIEnv

Accessing Java code from Native

Native code access the javaVM featured by calling JNI functions. JNI functions are exposed by inteface pointer.An interface pointer is a pointer to pointer pointer. The pointer points to an array of pointers, each of a pointer will point to an interface function

Jni interface pointer will be accessed by JNIEnv *

Loading native methods in java code

Native methods are loaded inside java program using System.loadLibrary method

To Learn more about the JNI in depth, Follow the Page

JNI Programming

Steps to add JNI in Android Studio Project

Create CMake File under src/main/cpp/CMakeLists.txt .CMakeLists.txt file contains a set of directives and instructions describing the project's source files and targets (executable, library, or both).

Open the CMakeLists.txt file and add the cmake latest version as cmake_minimum_required(VERSION 3.18.1)

name the project using project("project_name"), in our sample we have named the jni project as MyLibrary, hence project("MyLibrary")

Add the library using add_library(), in this sample, our library name is MyLibrary, hence i declared it as add_library(MyLibrary SHARED native-lib.cpp)

CMake Configuration

Add cmake path and version under externalNativeBuild in the build.gradle file

Create a source file under cpp folder. In this sample we have created native-lib.cpp

Declare an init method and load the library inside the init method using System.loadLibrary()

System.loadLibrary("library_name") will get the library name as a parameter and load the library in runtime during the initialization of the android activity

After that declare the native method using keyword external(in kotlin) or using native. This keyword is used to denote that the declared method is not created in kotlin or java but created in jni. if it was not created inside jni, android studio will suggest to create that method. In our sample we will create a method called echo which will accept a String as an argument and return

inside the native-lib.cpp file, import jni headers and string. Create a method name with mangled named structure along with the parameters.To know about mangled method name refer here.In our example, I have created a method called echo which will validate the pramaters and return a string

if the kotlin class pass the string argument as "ping" , then the jni method will return "pong". otherwise, it will return "invalid".

Below is the jni implementaion of the method echo

Call the native method from activity like shown below