JNI动态代理示例

2022-02-18

JNI动态代理示例

HelloWorld.class

1
2
3
4
5
6
7
public class HelloWorld{
static{
System.loadLibrary("helloworld");
}

public native int add(int a, int b);
}

libhelloworld.so

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <jni.h>

#define LOG_TAG "DemoInfo"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)

jint add(JNINev *nev , jobject jobj , jint a , jint b){
return a+b;
}

//编写 Methods 结构体
static JNINativeMethod getMethods[] = {
{"add", "(II)I", (void *)add},
}

//调用 RegisterNatives 函数动态注册接口
static int registerNativesMethods(JNIEnv* env, const char* classname,
JNINativeMethod* getmethods, int methodnum){
jclass clazz = env->FindClass(classname);   
if (clazz == NULL){       
return JNI_FALSE;   
}   
if (env->RegisterNatives(clazz,getmethods,methodnum) < 0){
return JNI_FALSE;   
}   
return JNI_TRUE;
}

static int registerNatives(JNIEnv *env){   
const char* className = "com/example/helloworld/MainActivity";   
return registerNativesMethods(env,className,getMethods,sizeof (getMethods) / sizeof(getMethods[0]));
}

//启动调用,动态注册JNI接口
JNIEXPORT jint JNI_onLoad(javaVM *vm, void *reserved){
JNIEnv* env = NULL;

if (vm->GetEnv((void**)(&env),JNI_VERSION_1_6) != JNI_OK){
return -1;
}

//确定env不等于空
assert(env != NULL);

if (!registerNatives(env)){
return -1;
}

return JNI_VERSION_1_6;
}

On_Load 方法

On_Load在动态注册中起核心作用,在系统调用System.loadLibrary(“helloworld”)时,
会首先调用On_Load方法,即生命周期的第一个方法。

getMethods 结构体

他的原型是一个JNINativeMethod结构体
signature 函数签名可以通过 javap -s -p 类名 来获取

1
2
3
4
5
6
7
8
typedef struct{
// JAVA中native函数的名字
const char* name;
// JAVA中native函数的签名信息,用字符串表示,为参数与返回值类型的结合体
const char* signature;
// JNI层对应的函数指针
void* fnPtr;
}JNINativeMethod;