Android Studio中JNI动态注册

1.动态注册的优缺点

需要我们手动建立联系,增加代码量,效率提高

允许自己定义函数名称.(native层的函数名称随便取,不需要遵守格式了)

2.在动态注册中 需要在.c文件中加入2个重要的函数和一个结构体,这三个函数分别是

jint JNI_OnLoad(JavaVM* vm, void* reserved){}

static int registNativeMethod(JNIEnv *env) {}

NINativeMethod nativeMethod 结构体.

在Android中使用 System.loadlibrary()方法加载动态库时,JVM会调用jni库中的JNI_OnLoad()函数, 所以我们可以在这个函数中 设置一些初始化操作.

这个函数不重写的话默认也是有的

在jni.h头文件中可以查看这个函数.

其中返回值jint代表的是动态库 需要的jni版本,如果jvm不识别 则不能加载这个库.


static int registNativeMethod(JNIEnv *env) {} 方法中 参数为JNIEnv指针

NINativeMethod nativeMethod 结构体.

中参数的含义

1.name 为Java代码中native方法的名称

2.signature:为方法的签名

3.fnPtr:是一个函数指针,指向jni层的一个函数,也就是java层和native层建立联系的函数


signature:方法签名的获取方法如下

编译项目后再app/build/intermediates/中 找到javac文件夹


找到对应的类右键单击选择open In->terminal



在命令窗口输入javap  -s  则会得到方法签名


开始搬砖,码代码:

1. 设置native方法 (注意这里因为使用动态注册 在动态注册的时候没有使用JNI对应的函数名称[任意命名的] 所以这里方法上会爆红 原因是在.c代码中 找不到对应的函数 我们可以不用管它)


2.在.c代码中加入对应的JNI_OnLoad(),registNativeMethod()方法 以及JNINativeMethod nativeMethod 结构体,内容如下:

extern "C"

JNIEXPORT jint JNICALL

native_txt(JNIEnv *env, jobject clazz, jstring msg) {

const char *p_msg = env->GetStringUTFChars(msg, JNI_FALSE);

    __android_log_print(ANDROID_LOG_INFO, "jni-test", "method = %s, msg = %s", __FUNCTION__, p_msg);

return 0;

}

extern "C"

JNIEXPORT jint JNICALL

//这里名字任意命名的

native_static_1text(JNIEnv *env, jclass clazz, jstring msg) {

const char *p_msg = env->GetStringUTFChars(msg, JNI_FALSE);

    __android_log_print(ANDROID_LOG_INFO, "jni-test", "method = %s, msg = %s", __FUNCTION__, p_msg);

    return 0;

}

static const JNINativeMethod nativeMethod[] = {

{"text",        "(Ljava/lang/String;)I", (void *) native_txt},

        //第一个参数 java代码中 native方法的名称  第二个是方法签名  最后一个参数是对应上面的函数名称

        {"static_text", "(Ljava/lang/String;)I", (void *) native_static_1text}

};

static int registNativeMethod(JNIEnv *env) {

int result = -1;

    //注意这里类的全文件 需要 使用/替换.

    jclass aclzz = env->FindClass("com/net/jnidynamic/JNIUtils");

    if (env->RegisterNatives(aclzz, nativeMethod,

                            sizeof(nativeMethod) /sizeof(nativeMethod[0])) ==JNI_OK) {

result =0;

    }

return result;

}

jint JNI_OnLoad(JavaVM* vm, void* reserved){

JNIEnv *env =NULL;

    int result = -1;

    if (vm->GetEnv((void **) &env, JNI_VERSION_1_1) ==JNI_OK) {

if (registNativeMethod(env) ==JNI_OK) {

result =JNI_VERSION_1_6;

        }

return result;

    }

}


结束:

编译出so文件  加入libs文件夹 (步骤省略 同静态注册)

运行程序得到结果


©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容