美文网首页
Android studio实现动态注册Native方法

Android studio实现动态注册Native方法

作者: WhenMeet | 来源:发表于2020-03-26 22:45 被阅读0次

      说到动态就有静态,但是静态的注册在上一篇文章中已经包含了,这里就不在赘述了,直接说动态实现。
      这里我们分步走。

    • 1.创建android工程
    选择普通工程
    项目命名

      不出意外,项目一会就建立完成。

    • 2.关联NDK
    打开项目配置
    选择NDK安装位置

      选择好了之后,点击OK即可。
      这里说一下,然后如果没有配置NDK环境变量的,需要给系统配置一下环境变量,我的是mac直接运行命令行:

    vim ./.bash_profile
    

    打开后,添加

    export NDK_HOME=填写你的NDK安装路径
    export PATH=$PATH:$NDK_HOME
    
    • 3.建立C++文件

      这里我起名NdkDynamic,在java包下新建了jni包,把类放在里面,内容如下:

    #include <stddef.h>
    #include "jni.h"
    
    #define JNI_CLASS "com/simple/dynamicdemo/NdkTest" //定义native方法的java文件
    
    /**
     * 返回一个字符串
     * **/
    JNIEXPORT jstring JNICALL native_hello(JNIEnv *env, jclass clazz) {
        return env->NewStringUTF("Hello from C++");
    }
    
    /**
     * 求两个int的值
     * **/
    JNIEXPORT jint JNICALL native_add(JNIEnv *env, jobject object, jint a, jint b) {
        return a + b;
    }
    
    /**
     * 方法数组,JNINativeMethod的第一个参数是Java中的方法名,第二个参数是函数签名,第三个参数是对应的方法指针,
     * java方法的签名一定要与对应的C++方法参数类型一致,否则注册方法可能失败
     * **/
    static JNINativeMethod method_table[] = {
            {"native_hello", "()Ljava/lang/String;", (void *) native_hello},
            {"native_add",   "(II)I",                (void *) native_add}
    };
    
    /**
     * 默认会调用的方法,这里把方法注册好
     **/
    JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
        //OnLoad方法是没有JNIEnv参数的,需要通过vm获取。
        JNIEnv *env = NULL;
        if (vm->AttachCurrentThread(&env, NULL) == JNI_OK) {
            //获取对应声明native方法的Java类
            jclass  clazz = env->FindClass(JNI_CLASS);
            if (clazz == NULL) {
                return JNI_FALSE;
            }
            //注册方法,成功返回正确的JNIVERSION。
            if (env->RegisterNatives(clazz, method_table, sizeof(method_table)/ sizeof(method_table[0]))==JNI_OK) {
                return JNI_VERSION_1_4;
            }
        }
        return JNI_FALSE;
    }
    

      这里的JNI_CLASS我们需要更改成我们待会调用这个C++的java类,根据需要更改包名,这里我们用到了method_table这个数组来注册我们的方法,一,三介绍了,下面给一下第二个参数的签名对应列表。


    签名列表对应
    • 4.建立Android.mk和配置build.gradle

      我们在刚才新建的jni文件夹下,新建Android.mk文件,内容如下:

    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_MODULE := JNITest
    LOCAL_SRC_FILES := NdkDynamic.cpp
    LOCAL_LDFLAGS += -llog
    include $(BUILD_SHARED_LIBRARY)
    

      这里的LOCAL_MODULE就是我们最后依赖文件名称,LOCAL_SRC_FILES就是我们的C++文件,然后进入app下的build.gradle,添加如下部分:

            externalNativeBuild {
                ndkBuild {
                    abiFilters "arm64-v8a", "armeabi-v7a", "x86"
                }
            }
    

      以及

        externalNativeBuild {
            ndkBuild {
                path "src/main/jni/Android.mk"
            }
        }
    

      示意图如下:


    gradle配置示意图
    • 5.调用实现

      返回我们的第三步,看到JNI_CLASS最后为NdkTest,那我们就新建一个NdkTest的java类,如下:

    public class NdkTest {
    
        static {
            System.loadLibrary("JNITest");
        }
    
        public native  String native_hello();
    
        public native int native_add(int a,int b);
    
    }
    

      需要注意的是这里的JNITest和我们的Android.mk里面的LOCAL_MODULE是对应的,不要混淆了,最后我们在MainActivity中调用一下,如下:

    public class MainActivity extends AppCompatActivity {
    
        public NdkTest ndkTest;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ndkTest = new NdkTest();
            Log.d("MainActivity", ndkTest.native_add(8,9) + "");
        }
    }
    
    

      成功打印!大功告成。

    相关文章

      网友评论

          本文标题:Android studio实现动态注册Native方法

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