Jni学习1--静态注册和动态注册

1.jni 静态注册

第一步:新建java类:


    System.loadLibrary后面会讲到

第二步:通过javah  命令生成.h文件                                             (固定命令)        (包名)

C:\MyNDKTest\mylibrary\build\intermediates\classes\release>javah  -jni ndk.example.com.mylibrary.JniTest

注意:找到class文件的包名的上一级目录,否则无法生成.h文件             

第三步:将生成的h文件拷贝到jni目录,然后新建一个cpp或者c文件,内容如下:

         在jni生成的getMax函数:Java_ndk_example_com_mylibrary_JniTest_getMax

    jni函数命名规则: 1 .包名+类名+函数名

                               2.java包名的“.”改成“_”

                              3.如果java函数名签名里面多了“_”则在前面加1

                                 比如:java包名com.test  类名Class_getmin

                                那么生成com_test_Class_1getmin()函数

#include <jni.h>
/* Header for class ndk_example_com_mylibrary_JniTest */

#ifndef _Included_ndk_example_com_mylibrary_JniTest
#define _Included_ndk_example_com_mylibrary_JniTest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     ndk_example_com_mylibrary_JniTest
 * Method:    getMax
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_ndk_example_com_mylibrary_JniTest_getMax
  (JNIEnv *evn, jobject, jint num1, jint num2){
     if(num1>num2) return num1
     else return num2;
}

#ifdef __cplusplus
}
#endif
#endif
第四部:生成jar和so

    使用命令gradlew makeJar命令生成jar 和so,参考 https://mp.csdn.net/postedit/79502214 


1.jni 动态注册

 第一步:定义方法名:
JNIEXPORT jint JNICALL getMax(JNIEnv *evn, jobject jobject1, jint num1, jint num2){
    LOGD("-------------------------getMax----------------------");
    return (num1>num2)?num1:num2;
}
JNIEXPORT void JNICALL test(JNIEnv *evn, jobject jobject1){
    LOGD("-------------------------test----------------------");
}


第二步:定义 JNINativeMethod数组
JNINativeMethod method_table[] = {
        {"getMax", "(II)I", (int*) getMax},
        {"test", "()V", (void*) test}
};


第三步:重写JNI_OnLoad
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){
     jclass myClass;
     JNIEnv* env = NULL; //注册时在JNIEnv中实现的,所以必须首先获取它
     jint result = -1;
     if((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK) //从JavaVM获取JNIEnv,一般使用1.4的版本
         return -1;
     myClass = (*env)->FindClass(env, className);
     if(myClass == NULL)
     {
         return -1;
     }
     int size=sizeof(method_table)/sizeof(method_table[0]);
     if((*env)->RegisterNatives(env,myClass,method_table,size)<0)
     {
         return -1;
     }
    return JNI_VERSION_1_4; //这里很重要,必须返回版本,否则加载会失败。
}
完整的C代码如下:

#include <jni.h>
#include "stddef.h"
#include <android/log.h>
static const char *TAG = "Test";
#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO,  TAG, fmt, ##args)
#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)

 #ifndef _Included_ndk_example_com_mylibrary_JniTest
 #define _Included_ndk_example_com_mylibrary_JniTest
 #ifdef __cplusplus
 extern "C" {
 #endif
JNIEXPORT jint JNICALL getMax(JNIEnv *evn, jobject jobject1, jint num1, jint num2){
    LOGD("-------------------------getMax----------------------");
    return (num1>num2)?num1:num2;
}
JNIEXPORT void JNICALL test(JNIEnv *evn, jobject jobject1){
    LOGD("-------------------------test----------------------");
}
//方法数组,JNINativeMethod的第一个参数是Java中的方法名,第二个参数是函数签名,第三个参数是对应的方法指针。
//Java方法的签名一定要与对应的C++方法参数类型一致,否则注册方法可能失败。
JNINativeMethod method_table[] = {
        {"getMax", "(II)I", (int*) getMax},
        {"test", "()V", (void*) test}
};
static const char* const className="ndk/example/com/mylibrary/JniTest";

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){
     jclass myClass;
     JNIEnv* env = NULL; //注册时在JNIEnv中实现的,所以必须首先获取它
     jint result = -1;
     if((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK) //从JavaVM获取JNIEnv,一般使用1.4的版本
         return -1;
     myClass = (*env)->FindClass(env, className);
     if(myClass == NULL)
     {
         return -1;
     }
     int size=sizeof(method_table)/sizeof(method_table[0]);
     if((*env)->RegisterNatives(env,myClass,method_table,size)<0)
     {
         return -1;
     }
    return JNI_VERSION_1_4; //这里很重要,必须返回版本,否则加载会失败。
}
#ifdef __cplusplus
}
#endif
#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值