美文网首页
【进阶解密】JNI初学篇(二)-动态注册

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

作者: 南山村靓仔 | 来源:发表于2020-05-21 17:58 被阅读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

    相关文章

      网友评论

          本文标题:【进阶解密】JNI初学篇(二)-动态注册

          本文链接:https://www.haomeiwen.com/subject/oqbzohtx.html