1、实现效果

2、Java代码
package com.hvm.vender.jni_01;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import com.hvm.vender.jni_01.databinding.ActivityMainBinding;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
public static String TAG = MainActivity.class.getSimpleName() + "_JAVA";
static {
System.loadLibrary("jni_01");
}
private ActivityMainBinding binding;
public static final int NUMBER = 100;
public String name = "daxiaa";
public static int age = 30;
public int count = 800;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
initListener();
}
private void initListener() {
binding.btnUpdate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "修改之之前的值: " + name);
changeName();
Log.d(TAG, "修改之后的值: " + name);
}
});
binding.btnUpdate2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "修改之之前的值: " + age);
changeAge();
Log.d(TAG, "修改之后的值: " + age);
}
});
binding.btnCallback.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
callBack();
}
});
binding.btnCallback2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String data = javaToNativeNoParams();
Log.d(TAG, "Java调用C++函数拿到的返回值: " + data);
}
});
binding.btnJavaC.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int age = 29;
String sex = "boy";
int[] array = {1, 2, 3, 7, 8, 7};
String[] strs = new String[]{"daxiaa", "pig", "dog"};
javaToNativeParams(age, sex, array, strs);
}
});
binding.btnJavaCObj.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Student student = new Student();
javaToNativeObj(student, "hello world");
}
});
binding.btnCJavaObj.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Student student = nativeNewObj();
Log.d(TAG, "C++创建的对象返回值: "+student.toString());
}
});
binding.btnGlobalReference.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
globalReference();
}
});
binding.btnExtern.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
extern();
}
});
}
native void extern();
native void globalReference();
native Student nativeNewObj();
native void javaToNativeObj(Student student, String hello_world);
native void javaToNativeParams(int age, String sex, int[] array, String[] strs);
native String javaToNativeNoParams();
public String nativeToJava2(int a, String b) {
Log.d(TAG, " C++调用Java中的函数 a = " + a + ",b = " + b);
return "c++ is pig";
}
public void nativeToJava(int a, String b) {
Log.d(TAG, "nativeToJava: C++调用Java中的函数a = " + a + ",b = " + b);
}
native void callBack();
native void changeName();
native static void changeAge();
}
3、Native代码
#include <jni.h>
#include <string>
#include <android/log.h>
#define TAG "MainActivity_C"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
extern "C"
JNIEXPORT void JNICALL
Java_com_hvm_vender_jni_101_MainActivity_changeName(JNIEnv *env, jobject thiz) {
jclass j_class = env->GetObjectClass(thiz);
jfieldID j_Id = env->GetFieldID(j_class, "name", "Ljava/lang/String;");
jstring j_name = static_cast<jstring>(env->GetObjectField(thiz, j_Id));
char *c_name = const_cast<char *>(env->GetStringUTFChars(j_name, NULL));
LOGD("在c中获取到的name:%s\n", c_name);
jstring j_tem = env->NewStringUTF("dog");
env->SetObjectField(thiz, j_Id, j_tem);
jfieldID count_jfieldId = env->GetFieldID(j_class, "count", "I");
jint j_count = env->GetIntField(thiz, count_jfieldId);
int count = j_count;
LOGD("在c中获取到的coun:%d\n", count);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_hvm_vender_jni_101_MainActivity_changeAge(JNIEnv *env, jclass j_class) {
jfieldID jfield_Id = env->GetStaticFieldID(j_class, "age", "I");
jint j_age = env->GetStaticIntField(j_class, jfield_Id);
int c_age = j_age;
LOGD("在c中获取到的age:%d\n", c_age);
jint temp = 100;
env->SetStaticIntField(j_class, jfield_Id, temp);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_hvm_vender_jni_101_MainActivity_callBack(JNIEnv *env, jobject thiz) {
jclass j_class = env->GetObjectClass(thiz);
jmethodID jmethod_Id = env->GetMethodID(j_class, "nativeToJava", "(ILjava/lang/String;)V");
jstring temp = env->NewStringUTF("hello world");
jint number = 100;
env->CallVoidMethod(thiz, jmethod_Id, number, temp);
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_hvm_vender_jni_101_MainActivity_javaToNativeNoParams(JNIEnv *env, jobject thiz) {
LOGD("Java调用C++中的函数");
jclass j_class = env->GetObjectClass(thiz);
jmethodID jmethod_Id = env->GetMethodID(j_class, "nativeToJava2",
"(ILjava/lang/String;)Ljava/lang/String;");
jstring temp = env->NewStringUTF("hello world");
jint number = 800;
jstring jstring_temp = static_cast<jstring>(env->CallObjectMethod(thiz, jmethod_Id, number,
temp));
char *data = const_cast<char *>(env->GetStringUTFChars(jstring_temp, NULL));
LOGD("C++调用Java拿到的值:%s\n", data);
jstring result = env->NewStringUTF("java is pig");
return result;
}
extern "C"
JNIEXPORT void JNICALL
Java_com_hvm_vender_jni_101_MainActivity_javaToNativeParams(JNIEnv *env, jobject thiz, jint age,
jstring sex, jintArray array,
jobjectArray strs) {
LOGD("基本数据类型:%d", age);
const char *sexStr = env->GetStringUTFChars(sex, NULL);
LOGD("字符串:%s", sexStr);
jint *jintArray = env->GetIntArrayElements(array, NULL);
int length = env->GetArrayLength(array);
for (int i = 0; i < length; ++i) {
LOGD("遍历int类型数组:%d", *(jintArray + i));
}
env->ReleaseIntArrayElements(array, jintArray, 0);
int size = env->GetArrayLength(strs);
for (int i = 0; i < size; ++i) {
jstring jstringStr = static_cast<jstring>(env->GetObjectArrayElement(strs, i));
const char *str = env->GetStringUTFChars(jstringStr, NULL);
LOGD("遍历String类型数组:%s", str);
env->ReleaseStringUTFChars(jstringStr, str);
}
}
extern "C"
JNIEXPORT void JNICALL
Java_com_hvm_vender_jni_101_MainActivity_javaToNativeObj(JNIEnv *env, jobject thiz, jobject student,
jstring str) {
jclass j_class = env->GetObjectClass(student);
jstring j_string = env->NewStringUTF("daxiaa");
jmethodID j_methodId = env->GetMethodID(j_class, "setName", "(Ljava/lang/String;)V");
env->CallVoidMethod(student, j_methodId, j_string);
jmethodID j_static_methodId = env->GetStaticMethodID(j_class, "show", "()V");
env->CallStaticVoidMethod(j_class, j_static_methodId);
jmethodID j_return_methodId = env->GetMethodID(j_class, "getName", "()Ljava/lang/String;");
jstring jstringName = static_cast<jstring>(env->CallObjectMethod(student, j_return_methodId));
const char *nameChar = env->GetStringUTFChars(jstringName, NULL);
LOGD("调用Student对象中的getName函数返回值:%s", nameChar);
env->ReleaseStringUTFChars(jstringName, nameChar);
}
extern "C"
JNIEXPORT jobject JNICALL
Java_com_hvm_vender_jni_101_MainActivity_nativeNewObj(JNIEnv *env, jobject thiz) {
char *calssName = "com/hvm/vender/jni_01/Student";
jclass j_class = env->FindClass(calssName);
jstring name = env->NewStringUTF("Pig");
jobject j_object_student = env->AllocObject(j_class);
jmethodID j_methodId = env->GetMethodID(j_class, "setName", "(Ljava/lang/String;)V");
env->CallVoidMethod(j_object_student, j_methodId, name);
jmethodID constructMethodId = env->GetMethodID(j_class, "<init>", "(Ljava/lang/String;I)V");
jobject j_object_student2 = env->NewObject(j_class, constructMethodId, name,
150);
jmethodID j_getAgemethodId = env->GetMethodID(j_class, "getAge", "()I");
jint age = env->CallIntMethod(j_object_student2, j_getAgemethodId);
LOGD("调用Student对象中的getAge函数返回值:%d", age);
char *personClassName = "com/hvm/vender/jni_01/Person";
jclass personCalss = env->FindClass(personClassName);
jobject jobjectPerson = env->AllocObject(personCalss);
jmethodID jmethodIdSetName = env->GetMethodID(personCalss, "setName", "(Ljava/lang/String;)V");
env->CallVoidMethod(jobjectPerson, jmethodIdSetName, env->NewStringUTF("person is pig"));
jfieldID j_fieldIdPerson = env->GetFieldID(j_class, "person", "Lcom/hvm/vender/jni_01/Person;");
env->SetObjectField(j_object_student2, j_fieldIdPerson, jobjectPerson);
return j_object_student2;
}
jclass j_class;
extern "C"
JNIEXPORT void JNICALL
Java_com_hvm_vender_jni_101_MainActivity_globalReference(JNIEnv *env, jobject thiz) {
if (!j_class) {
char *personClassName = "com/hvm/vender/jni_01/Person";
jclass temp = env->FindClass(personClassName);
j_class = static_cast<jclass>(env->NewGlobalRef(temp));
}
jmethodID jmethod_Id = env->GetMethodID(j_class, "<init>", "()V");
jobject j_object = env->NewObject(j_class, jmethod_Id);
LOGD("全局引用测试");
}
extern int age;
extern void show();
extern "C"
JNIEXPORT void JNICALL
Java_com_hvm_vender_jni_101_MainActivity_extern(JNIEnv *env, jobject thiz) {
show();
}
#include <android/log.h>
#define TAG "MainActivity_C"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
int age = 99;
void show() {
LOGD("extern %d", age);
}
源码
gitee.com/daxiaa/jni-…