NDK开发(三) :JNI访问Java变量和方法
转载请以链接形式标明出处: 本文出自:103style的博客
本文操作以 Android Studio 3.4.2 版本为例
- NDK开发(一) :NDK入门指南
- NDK开发(二) :JNI的数据类型
- NDK开发(三) :JNI访问Java变量和方法
- NDK开发(四) :JNI操作Java数组
- NDK开发(五) :JNI实现文件加解密
- NDK开发(六) :JNI实现文件拆分和合并
前先阅读 JNI的数据类型。
目录
- JNI访问Java成员变量
- JNI访问Java静态变量
- JNI访问Java非静态方法
- JNI访问Java静态方法
- JNI访问Java构造方法
- 小结
- 参考文章
JNI访问Java成员变量
我们在 Demo HelloNDK 这里继续添加示例。
首先定义变量showText
:
public String showText = "Hello World";
添加native
方法accessField()
:
public native void accessField();
选中accessField
,按 Alt+Enter
快捷添加.cpp
中方法Java_com_example_myapplication_MainActivity_accessField
在方法中实现修改属性的逻辑:
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myapplication_MainActivity_accessField(JNIEnv *env, jobject instance) {
//获取类
jclass jcla = env->GetObjectClass(instance);
//获取类的成员变量showText的id
jfieldID jfId = env->GetFieldID(jcla, "showText", "Ljava/lang/String;");
jstring after = env->NewStringUTF("Hello NDK");
//修改属性id对应的值
env->SetObjectField(instance, jfId, after);
}
调用验证结果:
TextView accessFiledShow = findViewById(R.id.tv_access_filed_show);
String res = "before: " + showText;
//通过ndk 修改成员变量
accessField();
res += ", after:" + showText;
accessFiledShow.setText(res);
JNI访问Java静态变量
我们在 Demo HelloNDK 这里继续添加示例。
同上添加静态属性和 native
方法:
private static String staticString = "static string";
public native void accessStaticField();
按 Alt+Enter
快捷添加.cpp
中方法Java_com_example_myapplication_MainActivity_accessStaticField
,添加如下代码:
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myapplication_MainActivity_accessStaticField(JNIEnv *env, jobject instance) {
//获取类
jclass oClass = env->GetObjectClass(instance);
//获取静态变量id
jfieldID staticFid = env->GetStaticFieldID(oClass, "staticString", "Ljava/lang/String;");
//设置静态变量
jstring after = env->NewStringUTF("static field update in jni");
env->SetStaticObjectField(oClass, staticFid, after);
}
调用验证结果:
TextView accessStaticFiledShow = findViewById(R.id.tv_static_access_filed_show);
res = "before: " + staticString;
//通过ndk 修改静态变量
accessStaticField();
res += ", after:" + staticString;
accessStaticFiledShow.setText(res);
JNI访问Java非静态方法
我们在 Demo HelloNDK 这里继续添加示例。
同上添加Java
非静态方法和 native
方法:
public native String accessMethod();
public String getAuthName(String name) {
Log.e(TAG, "name = " + name);
return name;
}
按 Alt+Enter
快捷添加.cpp
中方法Java_com_example_myapplication_MainActivity_accessMethod
,添加如下代码:
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_myapplication_MainActivity_accessMethod(JNIEnv *env, jobject instance) {
//获取类
jclass jCla = env->GetObjectClass(instance);
//获取方法id 第二个参数:方法名 第三个参数:(参数)返回值 的类型描述
jmethodID methodID = env->GetMethodID(jCla, "getAuthName",
"(Ljava/lang/String;)Ljava/lang/String;");
jstring res = env->NewStringUTF("103style");
jobject objRes = env->CallObjectMethod(instance, methodID, res);
return static_cast<jstring>(objRes);
}
调用验证结果:
TextView tvName = findViewById(R.id.tv_auth_name);
res = "authName = " + accessMethod();
tvName.setText(res);
JNI访问Java静态方法
我们在 Demo HelloNDK 这里继续添加示例。
同上添加Java
静态方法和 native
方法:
private static int getRandomValue(int max) {
return new Random().nextInt(max);
}
public native int accessStaticMethod(int max);
按 Alt+Enter
快捷添加.cpp
中方法Java_com_example_myapplication_MainActivity_accessStaticMethod__I
,添加如下代码:
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_myapplication_MainActivity_accessStaticMethod__I(JNIEnv *env, jobject instance,
jint max) {
//获取类
jclass jCla = env->GetObjectClass(instance);
//获取静态方法的id
jmethodID methodID = env->GetStaticMethodID(jCla, "getRandomValue", "(I)I");
//调用静态方法
jint res = env->CallStaticIntMethod(jCla, methodID, max);
//返回结果
return res;
}
调用验证结果:
TextView staticMethodShow = findViewById(R.id.tv_static_method_show);
res = "accessStaticMethod(100) = " + accessStaticMethod(100);
staticMethodShow.setText(res);
JNI访问Java构造方法
我们在 Demo HelloNDK 这里继续添加示例。
同上添加 native
方法:
public native Date accessConstructor();
按 Alt+Enter
快捷添加.cpp
中方法Java_com_example_myapplication_MainActivity_accessConstructor
,添加如下代码:
extern "C"
JNIEXPORT jobject JNICALL
Java_com_example_myapplication_MainActivity_accessConstructor(JNIEnv *env, jobject instance) {
//得到TestClass对应的jclass
// jclass jCla = env->FindClass("com/example/myapplication/TestClass");
jclass jCla = env->FindClass("java/util/Date");
//获取构造函数的methodId 构造函数为 void函数 对应的方法名为<init>
jmethodID methodID = env->GetMethodID(jCla, "<init>", "()V");
jobject jTestClass = env->NewObject(jCla, methodID);
return jTestClass;
}
调用验证结果:
TextView staticConstShow = findViewById(R.id.tv_const_show);
res = accessConstructor().toString();
staticConstShow.setText(res);
小结
JNI
获取类的成员变量的ID调用GetFieldID
获取,通过Set[类型]Field
修改变量值。JNI
获取类的成员变量的ID调用GetStaticFieldID
获取,通过SetStatic[类型]Field
修改变量值。JNI
获取类的方法的ID调用GetMethodID
获取,通过Call[类型]Method
调用方法。JNI
获取类的静态方法的ID调用GetStaticMethodID
获取,通过CallStatic[类型]Method
调用方法。JNI
获取类的构造方法的ID调用GetMethodID
获取,通过NewObject
构造,构造函数名为"<init>"
。- Demo地址
参考文章
以上
相关文章
- java解析xml方法_详解Java解析XML的四种方法
- java局域网发送文件_Java如何实现局域网文件传输代码案例分享
- 二维数组赋值 java_java二维数组的赋值方法「建议收藏」
- Java打印数组的四种方式「建议收藏」
- java高级工程师面试情景题_Java高级工程师面试题III
- JAVA-FileInputStream之read方法「建议收藏」
- java生成时间戳类型_Java获取当前时间戳的方法有哪些
- java中random方法取值范围_Java Random.nextInt()方法,随机产生某个范围内的整数
- pytest的使用_java直接调用方法
- 【说站】java虚拟扩展方法如何实现
- java验证手机号正则表达式_Java使用正则表达式验证手机号和电话号码的方法「建议收藏」
- java的栈内存和堆内存_Java本地方法栈
- java.sql.SQLException: ORA-01008: 并非所有变量都已绑定的解决方法「建议收藏」
- Java排序方法
- Java截取字符串方法_java通过split截取字符串
- 【Groovy】Groovy 方法调用 ( 字符串切割 | 使用 Java 语法切割字符串 | 使用 Groovy 语法切割字符串直接为变量赋值 | 数组赋值给变量 变量个数小于等于数组长度 )
- 数据库写入Java实现MySQL数据库的写入操作(java向mysql)
- 数据库Java查询Oracle数据库:一种快捷、可靠的解决方案(java查询oracle)
- Java调用Redis实现高性能数据存储(java调用redis)
- Linux系统中下载Java的方法(linux下java下载)
- Java和Redis的配合安装方法(java redis安装)
- Java应用在Linux上乱码的原因及解决方法(java linux乱码)
- 合Java与Oracle联手打造崭新未来(java和oracle联)
- 数据库Java编程修改Oracle数据库的实践(java修改oracle)
- Java实现Redis队列锁功能(redis队列锁java)