JNI/NDK Java Call C/C++ Preface
_Through the first article, we learned about Android Studio+CMake environment for JNI/NDK development, and the second article explained the process of generating a simple so library file. So in the actual development process, we often have to make calls between two layers, such as C/C++ calling the Java layer, or Java calling the C/C++ layer. Only by calling each other between the two layers can we achieve high performance and security.
JNI/NDK Java Calls C/C++ to Write java Files
Generally speaking, it is easier for Java layer to call C/C++ layer code. More is the processing in C/C++ layer, which is the difficulty. Here we introduce the common types of string, int, arr array in C/C++ layer.
public class NativeUtils {
//1. Refer to the JIN/NDk library file (the library name is consistent with the C/C++ file name created)
static {
System.loadLibrary("jni-utils");
}
//2. Define native native methods (which call C/C++ to implement functions on behalf of this method)
//Processing strings with return values and no parameters
public native String JavaCallJNI();
//Processing int type with parameters and return values
public native int JavaCallJNISum(int num1, int num2);
//Processing int [] array type with parameters and return values
public native int[] JavaCallJNIArr(int[] arr);
}
JNI/NDK Java Calls C/C++ to Write C/C++ Files
_Through the last step, we have written the code of the java layer. Secondly, the specific implementation of calling C/C++ in the java layer is written here, according to the corresponding business needs to achieve the corresponding functions.
//1. Introducing Jni header file
#include <jni.h>
#include <stdlib.h>
#include <stdio.h>
//2. Writing C/C++ functions of JNI corresponding to NativeUtils
//C/C++ Function Interpretation - ------------------------------------------------------------------------------------------------------------------------------------------------------------
//JNIEXPORT JNI exports jstring function return value JNICALL JNI for invocation
//Java_full class name_NativeUtils method name (JNIEnv * env, jobject)
// Function Pointer jobject jobject in JNIEnv*env C/C++ Calls Class Object of Native Method
extern "C"
JNIEXPORT jintArray JNICALL
Java_com_aynu_androidjni_NativeUtils_JavaCallJNIArr(JNIEnv *env, jobject jobject,
jintArray arr_) {
//1. Get the elements of the arr array
jint *arr = env->GetIntArrayElements(arr_, NULL);
//2. Get the length of the arr array
jsize arrSize = env->GetArrayLength(arr_);
//3. Traversal arrays
for (int i = 0; i < arrSize; ++i) {
*(arr + i) += 10;
}
//4. Release memory
env->ReleaseIntArrayElements(arr_, arr, 0);
//5. Return arrays
return arr_;
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_aynu_androidjni_NativeUtils_JavaCallJNISum(JNIEnv *env, jobject jobject,
jint num1,jint num2) {
//1. Corresponding logical operations
return num1 + num2;
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_aynu_androidjni_NativeUtils_JavaCallJNI(JNIEnv *env, jobject jobject) {
//3. Write specific business logic
return env->NewStringUTF("C/C++ Say");
}
JNI/NDK Call
After we have written the java layer and C/C++ layer, we need to call them.
public class MainActivity extends AppCompatActivity {
private TextView mMsgTxt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
mMsgTxt = (TextView) findViewById(R.id.msg_txt);
NativeUtils nativeUtils = new NativeUtils();
//Java calls JNI
String msg = nativeUtils.JavaCallJNI();
//mMsgTxt.setText(msg);
//Java calls JNI to achieve the sum of two numbers
int sum = nativeUtils.JavaCallJNISum(10, 5);
//mMsgTxt.setText(String.format("10+5=%d", sum));
//Java calls JNI to implement each element in the array plus 10
int[] arr = new int[]{1, 2, 3, 4, 5};
int[] jniArr = nativeUtils.JavaCallJNIArr(arr);
StringBuilder buffer = new StringBuilder();
for (int aJniArr : jniArr) {
buffer.append(aJniArr).append(",");
}
mMsgTxt.setText(buffer.toString());
}
}
JNI/NDK results
After invoking, we will generate the corresponding so library file, and also show our final results.
Processing results of type int
Processing the results of array types
Processing string type results
JNI/NDK Concluding remarks
_above is the project of using Android studio + CMake to build Java calling C++ code flow in JNI/NDK development. If there are misunderstandings, please leave more comments.