【进阶解密】JNI初学篇(二)-动态注册

2020-05-21  本文已影响0人  南山村靓仔

上一篇,我们讲到了JNI的静态注册,没看过的,按需查看
【进阶解密】JNI初学篇(一)-静态注册 https://www.jianshu.com/p/993c8f2d6857

今天我们讲下动态注册
主要步骤为:
1、java中定义Native方法
2、编写C/C++文件,实现jni接口方法,以及JNI_OnLoad方法
3、编译so库
4、java加载so库,调用native方法

1、新建java类,定义Native方法getHello

package jni.com.cj.constom.jnitest;

/*
* 动态注册方式
* */
public class JNITest2 {
    static {
        System.loadLibrary("mgjnitest2");
    }

    public static native String getHello();
}

2、新建文件jni_com_cj_constom_jnitest_JNITest.c ,实现jni接口方法,以及JNI_OnLoad方法

注意:C语言和C++的实现存在一些差异,GetEnv、FindClass、RegisterNatives方法参数有差异,若要用C++实现,就自行搜索下其他文章哈,文章很多~
下面是C语言的实现方式

#include <jni.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

JNIEXPORT jstring  JNICALL get_Hello(JNIEnv *env, jclass type) {
    return (*env)->NewStringUTF(env, "Hello from JNI 动态注册测试!");
}


static JNINativeMethod g_methods[] = {
        {"getHello",//java定义的native方法名
         "()Ljava/lang/String;", //()表示无参数;Ljava/lang/String表示返回String类型
          (void *) get_Hello //JNI中实现的方法名
        }
};

JNIEXPORT int JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv *env;
    if ((*vm)->GetEnv(vm, (void **)&env,JNI_VERSION_1_6) != JNI_OK) {
        return JNI_FALSE;
    }
    const char *class_path = "jni/com/cj/constom/jnitest/JNITest2";//这里对应native的java类
    jclass javaClass = (*env)->FindClass(env,class_path);
    if (javaClass == NULL) {
        return JNI_FALSE;
    }

    int method_count = sizeof(g_methods) / sizeof(g_methods[0]);
    if ((*env)->RegisterNatives(env,javaClass, g_methods, method_count) < 0) {
        return JNI_FALSE;
    }

    return JNI_VERSION_1_6;
}

3、分别创建Android.mk、Application.mk:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := mgjnitest2
LOCAL_SRC_FILES := jni_com_cj_constom_jnitest_JNITest.c
include $(BUILD_SHARED_LIBRARY)
#APP_ABI := armeabi armeabi-v7a arm64-v8a x86
APP_ABI := all
APP_OPTIM := release

## 引用静态库
APP_STL := stlport_static
#NDK_TOOLCHAIN_VERSION=4.8
#APP_PLATFORM := android-14

APP_PLATFORM := android-16
APP_ALLOW_MISSING_DEPS=true

4、主项目点击事件代码:

 public void getJNIValue2(View view) {
        String test = JNITest2.getHello();
        Toast.makeText(getApplicationContext(), "value=" + test, Toast.LENGTH_SHORT).show();
    }

测试结果:

image.png
上一篇下一篇

猜你喜欢

热点阅读