您的位置:首页 > 移动开发 > Android开发

理解Android JNI

2016-12-16 21:40 141 查看
target a. 用最通俗的语言来描述JNI 到底是个什么鬼。

target b. 加载JNI库 , native函数

target c. 注册JNI函数 (方式与类型

target d. 啥也不说,先上图



a. 如上, 有了JNI层,Java与平台的实现层实现了隔离,这样就可以做到Java与平台的无关性,实现夸平台的兼容性扩展

b. 问题来了,JNI是以何种方式做到中间转化的呢?

莫急,一步步来

b.1 注册 Native方法,即JNI 函数 先将JNI的函数集 封装到JNINativeMethod sMethods 数组里 =



b.2 调用 jniRegisterNativeMethods 注册 上面的sMethods

如以下Bluetooth/btservice/AdapterService为例



b.3 从Native 对接到C层实现会封装在 funcPtr里, 以enableNative 为例



b.4 关于类型标志表 见以下图

以上后面跟的那些奇怪的符号,其实就是参考下面的表,就是那么回事(没有啥高深莫测的……)



b.5 那么Java 是如何调用到JNI?(即访问到 JNI中的函数方法实现)

我相信你们一定知道,C层函数里如何调用标准C库的(通过加载呗,通过访问头文件(include到本地文件里,然后就像自家人想怎么用就怎么用!! ))

Java也是一样, 通过System.loadLibraray() 加载 , 它会进一步调用 JNI_OnLoad(JavaVM *jvm, void *reserved) (该部分是在JVM虚拟机里实现) 加载完了库之后(就像媳妇取过了们后),Java就可以在本地想干啥就干啥(当然要控制度哈。。。。)

可见以下代码



b.6 到里这里总结下, Java为了更好的隔离平台实现呢,自己搞了一层JVM虚拟机(很强大,有一本书专门讲它,但他也是罪魁祸首,Android常见的 性能瓶颈基本在他手上,所谓大内存也是被他吃的光光 。。。。 ) 然后JNI (就上按照上面的一套规则,运行在JVM上),他对接到Native(我们的C/C++),只要Java Load库成功后,就可以在本地像用自家东西一样 调用底层的函数实现方法。

c. 对了, 接着上面再扯扯 JNI内存回收的问题 。每个JNI 都会配对对应

static bool initNative(JNIEnv* env, jobject obj)

static bool cleanupNative(JNIEnv *env, jobject obj)

这两个函数做了啥呢。 前者,申请了NewGlobalRef 全局对象

后者, 释放了DeleteGlobalRef 内存这两部分都会放在 (调用者)Java 类里, 作为一个靠谱的代码狗,一定要在使用了 initNative之后, 记得调用cleanupNative 释放内存否则,你就是在埋坑,坑队友 。。。。。



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android