本文接着介绍如何在 C/C++ 中访问 Java,主要从以下几个方面来讲述:
我们直接看 Demo:
Java 层:
//定义一个被访问的类
public class TestJavaClass {
private String mString = "Hello JNI, this is normal string !";
private static int mStaticInt = 0;
}
//定义两个 native 方法
public native void accessJavaFiled(TestJavaClass testJavaClass);
public native void accessStaticField(TestJavaClass testJavaClass);
c++ 层:
//访问成员变量
extern "C"
JNIEXPORT void JNICALL
Java_com_yuandaima_myjnidemo_MainActivity_accessJavaFiled(JNIEnv *env, jobject thiz,
jobject test_java_class) {
jclass clazz;
jfieldID mString_fieldID;
//获得 TestJavaClass 的 jclass 对象
// jclass 类型是一个局部引用
clazz = env->GetObjectClass(test_java_class);
if (clazz == NULL) {
return;
}
//获得 mString 的 fieldID
mString_fieldID = env->GetFieldID(clazz, "mString", "Ljava/lang/String;");
if (mString_fieldID == NULL) {
return;
}
//获得 mString 的值
jstring j_string = (jstring) env->GetObjectField(test_java_class, mString_fieldID);
//GetStringUTFChars 分配了内存,需要使用 ReleaseStringUTFChars 释放
const char *buf = env->GetStringUTFChars(j_string, NULL);
//修改 mString 的值
char *buf_out = "Hello Java, I am JNI!";
jstring temp = env->NewStringUTF(buf_out);
env->SetObjectField(test_java_class, mString_fieldID, temp);
//jfieldID 不是 JNI 引用类型,不用 DeleteLocalRef
// jfieldID 是一个指针类型,其内存的分配与回收由 JVM 负责,不需要我们去 free
//free(mString_fieldID);
//释放内存
env->ReleaseStringUTFChars(j_string, buf);
//释放局部引用表
env->DeleteLocalRef(j_string);
env->DeleteLocalRef(clazz);
}
//访问静态成员变量
extern "C"
JNIEXPORT void JNICALL
Java_com_yuandaima_myjnidemo_MainActivity_accessStaticField(JNIEnv *env, jobject thiz,
jobject test_java_class) {
jclass clazz;
jfieldID mStaticIntFiledID;
clazz = env->GetObjectClass(test_java_class);
if (clazz == NULL) {
return;
}
mStaticIntFiledID = env->GetStaticFieldID(clazz, "mStaticInt", "I");
//获取静态成员
jint mInt = env->GetStaticIntField(clazz, mStaticIntFiledID);
//修改静态成员
env->SetStaticIntField(clazz, mStaticIntFiledID, 10086);
env->DeleteLocalRef(clazz);
}
访问一个类成员基本分为三部:
我们直接看 Demo:
Java 层
//等待被 native 层访问的 java 类
public class TestJavaClass {
//......
private void myMethod() {
Log.i("JNI", "this is java myMethod");
}
private static void myStaticMethod() {
Log.d("JNI", "this is Java myStaticMethod");
}
}
//本地方法
public native void accessJavaMethod();
public native void accessStaticMethod();
C++ 层:
extern "C"
JNIEXPORT void JNICALL
Java_com_yuandaima_myjnidemo_MainActivity_accessJavaMethod(JNIEnv *env, jobject thiz) {
//获取 TestJavaClass 对应的 jclass
jclass clazz = env->FindClass("com/yuandaima/myjnidemo/TestJavaClass");
if (clazz == NULL) {
return;
}
//构造函数 id
jmethodID java_construct_method_id = env->GetMethodID(clazz, "<init>", "()V");
if (java_construct_method_id == NULL) {
return;
}
//创建一个对象
jobject object_test = env->NewObject(clazz, java_construct_method_id);
if (object_test == NULL) {
return;
}
//获得 methodid
jmethodID java_method_id = env->GetMethodID(clazz, "myMethod", "()V");
if (java_method_id == NULL) {
return;
}
//调用 myMethod 方法
env->CallVoidMethod(object_test,java_method_id);
//清理临时引用吧
env->DeleteLocalRef(clazz);
env->DeleteLocalRef(object_test);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_yuandaima_myjnidemo_MainActivity_accessStaticMethod(JNIEnv *env, jobject thiz) {
jclass clazz = env->FindClass("com/yuandaima/myjnidemo/TestJavaClass");
if (clazz == NULL) {
return;
}
jmethodID static_method_id = env->GetStaticMethodID(clazz, "myStaticMethod", "()V");
if(NULL == static_method_id)
{
return;
}
env->CallStaticVoidMethod(clazz, static_method_id);
env->DeleteLocalRef(clazz);
}
Native 访问一个 Java 方法基本分为三部:
阅读量:2010
点赞量:0
收藏量:1