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 ProgrammingSteps 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