NDK动态注册方法

java的方法与c/c++代码的函数对应方式

静态方式

  • 通过Java_[包名]_[类名]_[方法名]的形式对应
  • 缺点是又臭又长, 不适合管理

动态方式

  • 采用自己喜欢的函数名定义方法
  • 简单, 漂亮

实现参考

静态

静态方法定义文件

动态

  • 需要在JNI_OnLoad里面完成注册
  • 头文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef __DYNAMIC_JNIDEMO_H__
#define __DYNAMIC_JNIDEMO_H__

#include <jni.h>

#ifdef __cplusplus
extern "C" {
#endif

jstring testDynamicRegister(JNIEnv* env, jobject obj);

#ifdef __cplusplus
}
#endif
#endif // __DYNAMIC_JNIDEMO_H__
  • 实现文件
    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    #include "dynamic_jnidemo.h"
    #include "log.h"

    #include <cstdio>

    /**
    * 方法对应表
    */
    static JNINativeMethod gMethods[] = {
    {"testDynamicRegister", "()Ljava/lang/String;", (void*)testDynamicRegister},//绑定
    };

    // 注册方法
    static int registerNatives(JNIEnv* env);
    static int registerNativeMethods(JNIEnv* env, const char* className,
    JNINativeMethod* gMethods, int numMethods);

    /*
    * System.loadLibrary("lib")时调用
    * 如果成功返回JNI版本, 失败返回-1
    */
    JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
    JNIEnv* env = NULL;
    jint result = -1;

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

    if (NULL == env) {
    LOGD_D("获取env失败!");
    return -1;
    }

    if (!registerNatives(env)) {//注册
    return -1;
    }
    LOGD_D("注册方法成功");
    //成功
    result = JNI_VERSION_1_4;

    return result;
    }
    /*
    * 为某一个类注册本地方法
    */
    int registerNativeMethods(JNIEnv* env, const char* className,
    JNINativeMethod* gMethods, int numMethods) {
    jclass clazz;
    clazz = env->FindClass(className);
    if (clazz == NULL) {
    LOGD_D("不能找到类: %s", className);
    return JNI_FALSE;
    }
    if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
    return JNI_FALSE;
    }

    return JNI_TRUE;
    }


    /*
    * 为所有类注册本地方法
    */
    static int registerNatives(JNIEnv* env) {
    const char* kClassName = "com/dasea/ndkjnidemo/JniDemo";//指定要注册的类
    return registerNativeMethods(env, kClassName, gMethods,
    sizeof(gMethods) / sizeof(gMethods[0]));
    }

    // native 方法
    jstring testDynamicRegister(JNIEnv* env, jobject obj)
    {
    LOGD_D("JAVA 调用这个方法了, 并且c++端会返回一个响应!");
    return env->NewStringUTF("动态注册JNI");
    }