目录
相关文章
Android NDK开发:java调用dll动态链接库方法
Android NDK开发:JNIEnv的原理
Android NDK开发:C修改Java的属性
Android NDK开发:C调用Java层方法
Android NDK开发:C创建Java层的对象
Android NDK开发:C操作Java层的数组
Native层变量管理
在Java中我们创建对象后,虚拟机会自动帮我们清理,但是在C语言中如果创建Java层的对象则需要我们手动进行管理,否则将会导致内存越来越大,接下来我以获取UUID为例进行演示,具体操作如下:
局部变量的管理:DeleteLocalRef
C语言代码:
#include "../com_itfitness_NdkDemo.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_com_itfitness_NdkDemo_LocalRef
(JNIEnv* env, jclass jclazz) {
//找到class对象
jclass ndkdemo_clazz = (*env)->FindClass(env, "Lcom/itfitness/NdkDemo;");
char* method_name = "<init>";
char* method_sign = "()V";
//构造方法
jmethodID constructor_method_id = (*env)->GetMethodID(env, ndkdemo_clazz, method_name, method_sign);
//创建对象
jobject jobj = (*env)->NewObject(env, ndkdemo_clazz, constructor_method_id);
//得到获取UUID的方法的id
jmethodID get_uuid_methodid = (*env)->GetMethodID(env,ndkdemo_clazz,"getUUID","()Ljava/lang/String;");
//调用获取UUID的方法
jstring j_uuid = (*env)->CallObjectMethod(env,jobj,get_uuid_methodid);
//将jstring转换为char*类型
char* c_uuid = (*env)->GetStringUTFChars(env, j_uuid,JNI_FALSE);
//打印UUID
printf("UUID = %s",c_uuid);
//删除对象(关键代码)
(*env)->DeleteLocalRef(env,jobj);
}
Java代码:
package com.itfitness;
import java.util.UUID;
public class NdkDemo {
static {
System.load("E:\\Project\\VS\\Native层变量管理\\x64\\Release\\Native层变量管理.dll");
}
/**
* 获取UUID
* @return
*/
public String getUUID() {
String uuid = UUID.randomUUID().toString();
uuid = uuid.replace("-", "");
return uuid;
}
public static void main(String[] args) {
LocalRef();
}
//局部变量
public native static void LocalRef();
}
执行结果:
全局变量的管理:DeleteGlobalRef
C语言代码:
#include "../com_itfitness_NdkDemo.h"
#include <stdio.h>
jstring global_string;
JNIEXPORT void JNICALL Java_com_itfitness_NdkDemo_createGlobal
(JNIEnv* env, jclass jclazz,jstring js) {
//创建全局对象
global_string = (*env)->NewGlobalRef(env, js);
}
JNIEXPORT jstring JNICALL Java_com_itfitness_NdkDemo_getGlobal
(JNIEnv* env, jclass jclazz) {
return global_string;
}
JNIEXPORT void JNICALL Java_com_itfitness_NdkDemo_deleteGlobal
(JNIEnv* env, jclass jclazz) {
//删除全局变量
(*env)->DeleteGlobalRef(env, global_string);
}
Java代码:
package com.itfitness;
import java.util.UUID;
public class NdkDemo {
static {
System.load("E:\\Project\\VS\\Native层变量管理\\x64\\Release\\Native层变量管理.dll");
}
/**
* 获取UUID
* @return
*/
public String getUUID() {
String uuid = UUID.randomUUID().toString();
uuid = uuid.replace("-", "");
return uuid;
}
public static void main(String[] args) {
createGlobal("奥特曼");
System.out.println("全局变量 = " + getGlobal());
deleteGlobal();
//删除对象后再打印会报错
System.out.println("全局变量 = " + getGlobal());
}
//创建全局变量
public native static void createGlobal(String val);
//获取全局变量
public native static String getGlobal();
//删除全局变量
public native static void deleteGlobal();
}
执行结果:
Native层静态缓存
在C语言中如果重复调用一个方法并且该方法中含有一个静态变量,那么只要不给该变量再次赋值它就会一直缓存上一次的值,具体演示如下:
C语言代码:
#include "../com_itfitness_NdkDemo.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_com_itfitness_NdkDemo_staticCache
(JNIEnv* env, jclass jclazz, jint jval) {
//给静态变量赋值
static jint static_val = NULL;
if (static_val == NULL) {
static_val = jval;
}
jint val = NULL;
//给非静态变量赋值
if (val == NULL) {
val = jval;
}
//打印
printf("静态变量 = %d,", static_val);
printf("非静态变量 = %d\n", val);
}
Java代码:
package com.itfitness;
import java.util.UUID;
public class NdkDemo {
static {
System.load("E:\\Project\\VS\\Native层变量管理\\x64\\Release\\Native层变量管理.dll");
}
public static void main(String[] args) {
staticCache(10);
staticCache(20);
staticCache(30);
}
public native static void staticCache(int val);
}
执行结果: