JNI

JNI:

Java Native Interface ;Java本地调用

JNI功能:

可以实现Java函数和Native函数的相互调用。Native函数一般指C/C++函数。

MediaScanner :

Paste_Image.png

Java层的MediaScanner分析 :

(1)加载JNI库:Java要调用Native函数,就必须通过一个位于JNI层的动态库才可以完成。
(2)动态库:运行时才加载的库。Linux平台so文件,Window平台dll文件。
(3)加载时机:原则上是在调用Native函数之前,通常是在一个static块中进行加载,通过调用System.loadLibrary(media_jni)。系统会根据不同的平台拓展成为真实的库,linux平台上是libmedia_jni.so库,window平台上是media_jni.dll库。

JNI层的MediaScanner分析 :

注册:将Java层的native函数和JNI层对应的实现函数关联起来,有了这种关联,调用Java层的native函数时,就能顺利转到JNI层对应的函数执行了。
android.media.MediaScanner.native_init()
android_media_MediaScanner_native_init()

注册JNI函数 :静态注册,动态注册。
静态注册:根据函数名来找到对应得JNI函数。
(1)先把java文件编译成.class文件
(2)利用javah生成.h头文件,android_media_MediaScanner.h
Java层 native函数查找JNI函数的过程。
当Java层调用native_init()函数,它会从对应得JNI库中寻找Java_android_media_MediaScanner_native_linit函数, 如果没找到,就会报错,如果找到,则会为这个native_init()函数和
Java_android_media_mediaScanner_native_linit函数建立一个关联关系,其实就是保存JNI层函数的指针。以后调用这个native_init()函数的时候,直接使用这个函数指针即可。
缺陷:
(1)需要编译所有声明了native函数的Java类,每个生成的class文件都需要用javah来编译。
(2) 初次调用的时候要根据函数名来搜索对应的JNI层函数来建立关联关系,这样会影响执行效率。
动态注册:
1 通过JNINativeMethod这种结构(结构体)来保存Java native函数和JNI函数。

Paste_Image.png

JNINativeMethod: Java中native函数的方法名+签名信息+函数指针;
2 通过AndoridRuntime.registerNativeMethods来完成注册工作,在其内部会通过JNIEnv.registerNatives来完成注册工作。
3 注册函数调用:当Java层通过System.loadLibrary加载完JNI库后,会在该库查找JNI_Onload函数,然后调用它,动态注册函数,便是在这里注册完成。

数据类型转换:###

基本数据类型转换

Paste_Image.png

注意: char在native层占16位。

引用数据类型转换

Paste_Image.png

注意:除class,String,Throwable以外其余的object类型都用jobject

JNIEnv:

Paste_Image.png

概念:是一个与线程相关的代表JNI环境的结构体。内部存储函数指针。
功能:提供一些JNI系统函数,通过这些函数可以做到
调用Java函数
操作jobject的很多事情

调用Java函数:
JNIEnv和JVM
不能在一个线程中使用另外一个线程的JNIEnv
调用JVM的attachCurrentThread,可以获得当前线程的JNIEnv结构体,通过这个结构体可以在后台线程回调Java函数。
当后台线程退出后需要调用,用JVM的dettachCurrentThread
通过JNIEnv操作jobject
操作jobeject的实质是操作这个对象的属性和方法。
jfieldID和jmethodID
(1)可以通过JNIEnvGetFieldID()GetMethodID() 获取jfieldID和jmethodID

Paste_Image.png

(2)获取之后,传入JNIEnv的CallVoidMethod 函数取调用Java方法。
(3)通过JNIEnv的get<TYPE>Field和set<TYPE>Field来获取jobject的属性和设置属性

jstring

(1) 调用JNIEnv的NewString()把一个本地字符串转换成jstring对象,Unicode字符串。
(2) 调用JNIEnv的NewUTFString()把一个本地的UTF-8字符串转换成jstring对象。
(3)getStringChars和getStringUTFChars可以把一个jstring对象转换成本地字符串。
(4)需要调用ReleaseStringChars和ReleaseStringUTFchars来释放对应的资源。

JNI签名

(1)参数值+返回值共同组成
(2)因为重载,所以仅根据函数名是无法找到相应的函数的,所以需要把参数值和返回值组合起来,这样才能顺利找到Java函数。

Paste_Image.png

垃圾回收

三种引用:
Local Reference:除了Global Reference,函数调用时传入的,或者在函数中创建jobject,一旦JNI函数返回,就有可能被回收。
Global Reference: 全局引用,如果不主动释放,不会被回收,当JNI层想要保存某个Java层的对象时,就可以使用Global Reference,要记住释放。
Weak Global Reference: 弱全局引用,在使用的过程中,可能被回收,所以在使用前,需要先检查JNIEnv.IsSameObject判断是否被回收了。

JNI中的异常处理

不会中断本地函数的执行,直到从JNI层返回时,才会在Java层抛出异常。
JNIEnv的三个函数:
(1)ExceptionOccured函数,用来判断是否发生异常。
(2)ExceptionClear函数,用来清理JNI层的异常。
(3)ExceptionThrow用来向Java层抛出异常。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,348评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,122评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,936评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,427评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,467评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,785评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,931评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,696评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,141评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,483评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,625评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,291评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,892评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,741评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,324评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,492评论 2 348

推荐阅读更多精彩内容