本文为作者(石岩)原创,转载请指明出处:
https://blog.csdn.net/a1002450926/article/details/79812815
JAVA层代码
public class JniTest {
public String key = "key:JniTest";
// 局部引用
public native void localRef();
// 创建全局引用
public native void createGlobalRef();
// 获取全局引用
public native String getGlobalRef();
// 释放全局引用
public native void deleteGlobalRef();
// 异常
public native void exception();
public static void main(String[] args) {
JniTest test = new JniTest();
test.createGlobalRef();
System.out.println(test.getGlobalRef());
test.deleteGlobalRef();
try {
test.exception();
} catch (Exception e) {
System.out.println("Java层捕捉到了异常:" + e.getMessage());
}
}
static {
System.loadLibrary("JniTest");
}
}
C层代码
#pragma once
#pragma execution_character_set("utf-8")
#define _CRT_SECURE_NO_WARNINGS
#include "com_shiyan_jni_JniTest.h"
#include<string.h>
/*
局部引用
模拟:循环创建数组
*/
JNIEXPORT void JNICALL Java_com_shiyan_jni_JniTest_localRef
(JNIEnv *env, jobject jobj){
int i = 0;
for (; i < 10; i++){
jclass cls = (*env)->FindClass(env, "java/util/Date");
jmethodID mid = (*env)->GetMethodID(env, cls, "<init>", "()V");
jobject jobj = (*env)->NewObject(env, cls, mid);
//通知垃圾回收期回收对象
(*env)->DeleteLocalRef(env, jobj);
}
}
//全局引用
jstring global_str;
/*
创建全局引用
*/
JNIEXPORT void JNICALL Java_com_shiyan_jni_JniTest_createGlobalRef
(JNIEnv *env, jobject jobj){
jstring obj = (*env)->NewStringUTF(env, "hello jni!");
global_str = (*env)->NewGlobalRef(env, obj);
}
/*
获取全局引用
*/
JNIEXPORT jstring JNICALL Java_com_shiyan_jni_JniTest_getGlobalRef
(JNIEnv *env, jobject jobj){
return global_str;
}
/*
释放全局引用
*/
JNIEXPORT void JNICALL Java_com_shiyan_jni_JniTest_deleteGlobalRef
(JNIEnv *env, jobject jobj){
(*env)->DeleteGlobalRef(env, global_str);
}
//弱全局引用
//节省内存,在内存不足时可以释放所引用的对象
//可以引用一个不常用的对象,如果为NULL,临时创建
//创建:NewWeakGlobalRef,销毁:DeleteGlobalWeakRef
/*
异常处理
*/
JNIEXPORT void JNICALL Java_com_shiyan_jni_JniTest_exception
(JNIEnv *env, jobject jobj){
jclass cls = (*env)->GetObjectClass(env, jobj);
jfieldID mid = (*env)->GetMethodID(env, cls, "key2", "Ljava/lang/String;");
//检测是否发生java异常
jthrowable exception = (*env)->ExceptionOccurred(env);
if (exception != NULL){
//让JAVA代码可以继续运行
//清空异常信息
(*env)->ExceptionClear(env);
//补救措施
mid = (*env)->GetFieldID(env, cls, "key", "Ljava/lang/String;");
}
//获取属性的值
jstring jstr = (*env)->GetObjectField(env, jobj, mid);
//jstring->c
char *str = (*env)->GetStringUTFChars(env, jstr, NULL);
//判断是否相等
if (_stricmp(str, "key:JniTest2") != 0){
//认为抛出异常,给JAVA层处理
jclass newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
(*env)->ThrowNew(env, newExcCls, "Key Value is not invalid!");
}
}