JNI入门(二): 动态注册

在JNI编程入门(一)当中,这种编写JNI的方法是静态注册,如果仔细研究会发现有以下问题:

  1. JNI 方法名字必须遵循规则且名字很长,可以看到java与C++函数之间的关系,不安全。
  2. JNI接口的头文件需要用户手动javah生成,非常不方便
  3. 程序运行效率低,因为初次调用native函数时需要根据根据函数名在JNI层中搜索对应的本地函数,然后建立对应关系,这个过程比较耗时

所以有没有更专业、通用的方法呢?

有,那就是动态注册,如果阅读Android源代码,会经常发现这种调用方式。

动态注册:

原理:利用 RegisterNatives方法,将java方法与JNI函数注册为一一对应关系。

现在将JNI编程入门(一)中的例子进行改写:

注意: 该native库在第一次被加载时,会调用JNI_OnLoad方法,在这个方法中,我们注册native函数,将java函数与C++函数进行对应映射。

在一个APP中,只有一个JavaVM,除非该APK进程死亡,否则JavaVM依然有效,而不同线程中JNIEnv则不相同,因此,JavaVM在第一使用时,可以保存下来,接下来在不同的线程环境中,通过该JavaVM可以提取到JNIEnv。

运行结果:

接下来给大家介绍下编译脚本:Android.mk, Application.mk

Android.mk文件位于项目jni/目录的子目录中,用于向构建系统描述源文件和共享库。定义 Application.mk、构建系统和环境变量所未定义的项目范围设置。

Android.mk 的语法用于将源文件分组为模块。模块是静态库、共享库或独立可执行文件。

LOCAL_PATH:=$(call my-dir)

LOCAL_PATH:表示源文件在开发树种的位置。构建系统提供的宏函数 my-dir 将返回当前目录(包含 Android.mk 文件本身的目录)

Include $(CLEAR_VARS):

CLEAR_VARS 指向特殊 GNU Makefile,在描述每个模块之前,必须声明此变量

LOCAL_MODULE:=native

    LOCAL_MODULE 存储要构建的模块的名称。构建系统在生存最终共享库文件时,会添加lib前缀和.so后缀,像这个工程,最终会生成libnative.so

     LOCAL_C_INCLUDES 指定相对于 NDK root 目录的路径列表,在编译所有源文件时添加到 include 搜索路径

    例如: LOCAL_C_INCLUDES := xx/xx

LOCAL_SRC_FILES:= NativeClass.cpp

    LOCAL_SRC_FILES 包含要构建到模块中的 C 或 C++ 源文件列表

    LOCAL_CFLAGS 为构建系统设置在构建 C 和 C++ 源文件时要传递的编译器标志

    LOCAL_STATIC_LIBRARIES 存储当前模块依赖的静态模块列表

    LOCAL_SHARED_LIBRARIES 此模块在运行时依赖的共享库模块列表

    LOCAL_LDILIBS 包含在构建共享库或可执行文件时要使用的其他链接器标志列表

    BUILD_SHARED_LIBRARY 帮助系统将所有内容连接到一起,此处生成共享so库

Application.mk

    APP_ABI

    可以使用 APP_ABI 选择不同的 ABI。默认情况下,NDK 构建系统为 armeabi ABI 生成机器代码。

    APP_PLATFORM

    包含目标 Android 平台的名称。

    NDK_TOOLCHAIN_VERSION

    选择 GCC 编译器的版本

ndk-build 文件为一个 shell 脚本,用途是调用正确的 NDK 构建脚本

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值