JNI原理

JNI实现原理

JNI系列:JavaVM和JNIEnv等原理
http://blog4jimmy.com/2017/11/242.html
http://blog4jimmy.com/category/the_java_native_interface_programmer_guide_and_specificationjni
http://blog.guorongfei.com/2017/01/24/android-jni-tips-md/
https://www.cnblogs.com/fnlingnzb-learner/p/7366025.html
https://www.zybuluo.com/cxm-2016/note/566619
https://blog.csdn.net/omnispace/article/details/73320940
反射:
http://blog4jimmy.com/2017/11/224.html

http://androidxref.com/8.0.0_r4/xref/libnativehelper/include/nativehelper/jni.h

插件机制:
https://github.com/tiann/epic/tree/master/library/src/main/cpp
https://blog.csdn.net/omnispace/article/details/73320940

JNI的实现可涉及两个关键类:JNIEnv和JavaVM。
JavaVM:这个代表java的虚拟机。所有的工作都是从获取虚拟机的接口开始的。
第一种方式,在加载动态链接库的时候,JVM会调用JNI_OnLoad(JavaVM* jvm, void* reserved)(如果定义了该函数)。第一个参数会传入JavaVM指针。
第二种方式,在native code中调用JNI_CreateJavaVM(&jvm, (void*)&env, &vm_args)可以得到JavaVM指针。
两种情况下,都可以用全局变量,比如JavaVM
g_jvm来保存获得的指针以便在任意上下文中使用。
Android系统是利用第二种方式Invocation interface来创建JVM的。

JNIEnv:JNI Interface Pointer, 是提供JNI Native函数的基础环境,线程相关,不同线程的JNIEnv相互独立。
�JNIEnv只在当前线程中有效。本地方法不 能将JNIEnv从一个线程传递到另一个线程中。相同的 Java 线程中对本地方法多次调用时,传递给该本地方法的JNIEnv是相同的。但是,一个本地方法可被不同的 Java 线程所调用,因此可以接受不同的 JNIEnv。

     JavaVM则可以在进程中的各线程间共享。理论上一个进程可以有多个JavaVM,但Android只允许一个(JavaVm and JIEnv)。需要强调的是JNIEnv是跟线程相关的。sdk文档中强调了do not cache JNIEnv*,要用的时候在不同线程中再通过JavaVM *jvm的方法来获取与当前线程相关的JNIEnv*。两者都可以理解为函数表(Function Pointer Table), 前者是使用Java程序创建的运行环境(从属于一个JVM)提供JNI Native函数。

注意点:
http://www.10tiao.com/html/330/201711/2653579453/1.html

pthread_key:
https://zhuanlan.zhihu.com/p/33411235

http://blog.csdn.net/zsl_oo7/article/details/71081291
http://wiki.jikexueyuan.com/project/jni-ndk-developer-guide/function.html

## 调用Java层的方法

1.  通过 `jclass clazz = env->FindClass("含有路径的类名");` 找到类
2.  通过 `jmethodID mid = env->GetMethodID(clazz,"方法名","方法签名信息");`找到Java层方法的ID 

    *   注意 jmethodID 是一个专门记录 Java 层方法的类型
    *   类似的还有一个 jfieldID
3.  通过 `env->CallxxxMethod(jobj,mid,param1,param2...);` 调用 Java 层的方法 

    *   CallxxxMethod 中的 xxx 是 Java 方法的返回值类型,比如 CallVoidMethod,CallIntMethod
    *   第一个参数是指调用哪个对象的方法,就是 Java 中`.`前面的那个对象
    *   第二个参数 Java 中的 MethodID
    *   后面的参数就是 Java 方法的参数了,其类型都要是 java 中能处理的类型,比如 jstring,jint,jobject

## get和set Java层的field

1.  通过 `jclass clazz = env->FindClass("含有路径的类名");` 找到类
2.  通过 `jfieldID fid = env->GetFieldID(clazz,"成员名","成员类型标示");`找到Java层成员变量的ID
3.  通过 `GetxxxField(env,obj,fid);` / `SetxxxField(env,obj,fid,value);` 来get/set相应的成员变量

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

推荐阅读更多精彩内容