安庆大理运城常德铜陵江西
投稿投诉
江西南阳
嘉兴昆明
铜陵滨州
广东西昌
常德梅州
兰州阳江
运城金华
广西萍乡
大理重庆
诸暨泉州
安庆南充
武汉辽宁

Android系统由Java语言写很差吗?为什么按语言来要这

9月25日 老巫婆投稿
  JNI概述
  JNI(JavaNativeInterface,Java本地接口)是一种编程框架使得Java虚拟机中的Java程序可以调用本地应用或库,也可以被其他程序调用;本地程序一般是用其它语言C,C或汇编语言编写的,并且被编译为基于本机硬件和操作系统的程序;在Android平台,为了更方便开发者的使用和增强其功能性,Android提供了NDK来更方便开发者的开发
  Android系统按语言来划分的话由两个世界组成,分别是Java世界和Native世界;那为何要这么划分呢?Android系统由Java写很差吗?除了性能的以外,最主要的缘由就是在Java诞生以前,就有不少程序和库都是由Native语言写的,所以,重复利用这些Native语言编写的库是十分必要的,何况Native语言编写的库具备更好的性能
  这样就产生了一个问题,Java世界的代码要怎么使用Native世界的代码呢?这就须要一个桥梁来将它们链接在一块儿,而JNI就是这个桥梁
  经过JNI,Java世界的代码就能够访问Native世界的代码,一样的,Native世界的代码也能够访问Java世界的代码
  JNI,全名JavaNativeInterface,是Java本地接口;JNI是Java调用Native语言的一种特性,通过JNI可以使得Java与CC机型交互;简单点说就是JNI是Java中调用CC的统称
  JNI:是java与其他语言通信的桥梁
  需要用到JNI技术的地方:
  需要调用java语言不支持的依赖于操作系统平台特性的一些功能
  为了整合一些以前的非java语言开发的系统
  为了节省程序的运行时间。必须采用其他语言(比如:cc)来提升运行效率
  JNI在android中的运用场景:
  热修复
  插件化
  逆向开发
  系统源码调用等为什么要有JNI?
  JNI允许程序员用其他编程语言来解决用纯粹的Java代码不好处理的情况;例如:Java标准库不支持的平台相关功能或者程序库;也用于改造已存在的用其它语言写的程序,供Java程序调用。许多基于JNI的标准库提供了很多功能给程序员使用,例如文件IO、音频相关的功能
  当然,也有各种高性能的程序,以及平台相关的API实现,允许所有Java应用程序安全并且平台独立地使用这些功能;Java层可以用来负责UI功能实现,而C负责进行计算操作
  JNI框架允许Native方法调用Java对象;就像Java程序访问Native对象一样方便;Native方法可以创建Java对象,读取这些对象,并调用Java对象执行某些方法。当然Native方法也可以读取由Java程序自身创建的对象,并调用这些对象的方法通常在以下几种情况下考虑使用JNI:
  对处理速度有要求
  Java代码运行速度要比本地代码(CC)运行速度慢一些,假设对程序的运行速度有较高的要求
  能够考虑使用CC编写代码,然后在通过Java代码调用基于CC编写的部分
  硬件控制
  如前面所述:Java运行在虚拟机中,和真实运行的物理硬件之间是相互隔离的,通常我们使用本地代码C实现对硬件驱动的控制,然后再通过Java代码调用本地硬件控制代码
  复用本地代码
  假设程序的处理逻辑已经由本地代码实现并封装成了库,就没有必要再又一次使用Java代码实现一次;直接复用该本地代码,即提高了编程效率,又确保了程序的安全性和健壮性局部引用与全局引用
  Java代码与本地代码里在进行參数传递与返回值复制的时候,要注意数据类型的匹配;对于int,char等基本类型直接进行拷贝就可以,对于Java中的对象类型,通过传递引用实现
  JVM保证全部的Java对象正确的传递给了本地代码;而且维持这些引用,因此这些对象不会被Java的gc(垃圾收集器)回收
  因此,本地代码必须有一种方式来通知JVM本地代码不再使用这些Java对象;让gc来回收这些对象
  JNI将传递给本地代码的对象分为两种:局部引用和全局引用
  局部引用:
  仅仅在上层Java调用本地代码的函数内有效,当本地方法返回时,局部引用自己主动回收
  全局引用:
  仅仅有显示通知VM时:全局引用才会被回收,否则一直有效,Java的gc不会释放该引用的对象局部引用
  默认的话,传递给本地代码的引用是局部引用
  全部的JNI函数的返回值都是局部引用premdtypefencescidn72langclassmdfencesmdendblocktycontaincmmodeLoadedspellcheckfalsestyleboxsizing:overflow:fontfamily:var(monospace);fontsize:0。9display:breakinside:textalign:whitespace:backgroundimage:backgroundposition:backgroundsize:backgroundrepeat:backgroundattachment:backgroundorigin:backgroundclip:backgroundcolor:rgb(248,248,248);position:relative!border:1pxsolidrgb(231,234,237);borderradius:3padding:8px4px6marginbottom:15margintop:15width:color:rgb(51,51,51);fontstyle:fontvariantligatures:fontvariantcaps:fontweight:400;letterspacing:orphans:2;textindent:0texttransform:widows:2;wordspacing:0webkittextstrokewidth:0textdecorationstyle:textdecorationcolor:jstringMyNewString(JNIEnvenv,jcharchars,jintlen){staticjclassstringClassNULL;static不能保存一个局部引用jmethodIDjcharArrayelemAif(stringClassNULL){stringClassenvFindClass(javalangString);局部引用if(stringClassNULL){returnNULL;exceptionthrown}}本地代码中创建的字符串为局部引用,当函数返回后字符串有可能被gc回收cidenvGetMethodID(stringClass,init,(〔C)V);resultenvNewStringUTF(stringClass,cid,HelloWorld);}pre
  尽管局部引用会在本地代码运行之后自己主动释放,可是有下列情况时;要手动释放:
  本地代码訪问一个非常大的Java对象时,在使用完该对象后;本地代码要去运行比較复杂耗时的运算时,由于本地代码还没有返回。Java收集器无法释放该本地引用的对象,这时,应该手动释放掉该引用对象
  本地代码创建了大量局部引用;这可能会导致JNI局部引用表溢出,此时有必要及时地删除那些不再被使用的局部引用
  比方:在本地代码里创建一个非常大的对象数组
  jni。h头文件里定义了JNI本地方法与Java方法映射关系结构体JNINativeMethod
  创建的工具函数,它会被未知的代码调用,在工具函数里使用完的引用要及时释放
  不返回的本地函数
  比如,一个可能进入无限事件分发的循环中的方法
  此时在循环中释放局部引用,是至关重要的,这样才干不会无限期地累积;进而导致内存泄露
  局部引用仅仅在创建它们的线程里有效;本地代码不能将局部引用在多线程间传递。一个线程想要调用还有一个线程创建的局部引用是不被同意的
  将一个局部引用保存到全局变量中,然后在其他线程中使用它,这是一种错误的编程全局引用
  在一个本地方法被多次调用时,能够使用一个全局引用跨越它们
  一个全局引用能够跨越多个线程,而且在被程序猿手动释放之前,一直有效;和局部引用一样,全局引用保证了所引用的对象不会被垃圾回收
  JNI同意程序猿通过局部引用来创建全局引用,全局引用仅仅能由NewGlobalRef函数创建
  以下是一个使用全局引用样例:premdtypefencescidn94langclassmdfencesmdendblocktycontaincmmodeLoadedspellcheckfalsestyleboxsizing:overflow:fontfamily:var(monospace);fontsize:0。9display:breakinside:textalign:whitespace:backgroundimage:backgroundposition:backgroundsize:backgroundrepeat:backgroundattachment:backgroundorigin:backgroundclip:backgroundcolor:rgb(248,248,248);position:relative!border:1pxsolidrgb(231,234,237);borderradius:3padding:8px4px6marginbottom:15margintop:15width:color:rgb(51,51,51);fontstyle:fontvariantligatures:fontvariantcaps:fontweight:400;letterspacing:orphans:2;textindent:0texttransform:widows:2;wordspacing:0webkittextstrokewidth:0textdecorationstyle:textdecorationcolor:jstringMyNewString(JNIEnvenv,jcharchars,jintlen){staticjclassstringClassNULL;。。。省略部分代码if(stringClassNULL){jclasslocalRefClsenvFindClass(javalangString);if(localRefClsNULL){returnNULL;}创建全局引用并指向局部引用stringClassenvNewGlobalRef(localRefCls);删除局部引用envDeleteLocalRef(localRefCls);推断全局引用是否创建成功if(stringClassNULL){returnNULL;outofmemoryexceptionthrown}}}pre
  在native代码不再须要訪问一个全局引用的时候,应该调用DeleteGlobalRef来释放它。假设调用这个函数失败。JavaVM将不会回收相应的对象Native方法注册
  静态注册
  新建xx。java也就是JNI对应的Java层的类其中定义好要使用的方法在xx。java目录下执行下面两条命令prespellcheckfalseclassmdfencesmdendblocktycontaincmmodeLoadedlangcidn115mdtypefencesstyleboxsizing:overflow:fontfamily:var(monospace);fontsize:0。9display:breakinside:textalign:whitespace:backgroundimage:backgroundposition:backgroundsize:backgroundrepeat:backgroundattachment:backgroundorigin:backgroundclip:backgroundcolor:rgb(248,248,248);position:relative!border:1pxsolidrgb(231,234,237);borderradius:3padding:8px4px6marginbottom:15margintop:15width:color:rgb(51,51,51);fontstyle:fontvariantligatures:fontvariantcaps:fontweight:400;letterspacing:orphans:2;textindent:0texttransform:widows:2;wordspacing:0webkittextstrokewidth:0textdecorationstyle:textdecorationcolor:javaccomexamplexx。javajavahcom。example。xxpre
  第二条命令会在当前目录下生成comexamplexx。h文件,其中会生成对应的C层方法,命名格式为包名类名方法名的格式,用分割静态注册就是根据方法名,将Java方法和JNI函数建立关联,但它有以下缺点:1、JNI层的函数名称过长;2、声明Native方法类需要用javah生成头文件3、初次调用Native方法时需要建立关联,影像效率(2)动态注册
  JNI中有一种结构用来记录Java的Native方法和JNI方法的关联关系,它就是JNINativeMethod,它在jni。h中被定义premdtypefencescidn108langclassmdfencesmdendblocktycontaincmmodeLoadedspellcheckfalsestyleboxsizing:overflow:fontfamily:var(monospace);fontsize:0。9display:breakinside:textalign:whitespace:backgroundimage:backgroundposition:backgroundsize:backgroundrepeat:backgroundattachment:backgroundorigin:backgroundclip:backgroundcolor:rgb(248,248,248);position:relative!border:1pxsolidrgb(231,234,237);borderradius:3padding:8px4px6marginbottom:15margintop:15width:color:rgb(51,51,51);fontstyle:fontvariantligatures:fontvariantcaps:fontweight:400;letterspacing:orphans:2;textindent:0texttransform:widows:2;wordspacing:0webkittextstrokewidth:0textdecorationstyle:textdecorationcolor:typedefstruct{Java方法的名字Java方法的签名信息voidfnPJNI中对应的方法指针}JNINativeMpre
  系统的MediaRecorder采用的就是动态注册,我们来看它的JNI层是怎么做的
  定义JNINativeMethod类型的数组gMethods,里面存储的就是MediaRecorder的Native方法与JNI层函数的对应关系premdtypefencescidn122langclassmdfencesmdendblocktycontaincmmodeLoadedspellcheckfalsestyleboxsizing:overflow:fontfamily:var(monospace);fontsize:0。9display:breakinside:textalign:whitespace:backgroundimage:backgroundposition:backgroundsize:backgroundrepeat:backgroundattachment:backgroundorigin:backgroundclip:backgroundcolor:rgb(248,248,248);position:relative!border:1pxsolidrgb(231,234,237);borderradius:3padding:8px4px6marginbottom:15margintop:15width:color:rgb(51,51,51);fontstyle:fontvariantligatures:fontvariantcaps:fontweight:400;letterspacing:orphans:2;textindent:0texttransform:widows:2;wordspacing:0webkittextstrokewidth:0textdecorationstyle:textdecorationcolor:frameworksbasemediajniandroidmediaMediaRecorder。cppstaticconstJNINativeMethodgMethods〔〕{{start,()V,(Void)androidmediaMediaRecordStart},。。。}pre
  其中start是java层的Native方法,对应的JNI层的函数为androidmediaMediaR()V是start方法的签名信息;定义完该数组后还需注册它,注册的函数为registerandroidmediaMediaRecorder
  JNIOnLoad函数会在调用System。LoadLibrary函数后调用;因此,注册函数就被统一定义在androidmediaMediaPlayer。cpp的JNIOnLoad函数中
  在registerandroidmediaMediaRecorder方法中返回了AndroidRuntime的registerNativeMethods函数,也就是会调用该方法
  在AndroidRuntime的registerNativeMethods函数中又返回了jniRegisterNativeMethods函数,它被定义在JNI帮助类JNIHelp。cpp中
  jniRegisterNativeMethods方法中最终通过调用的JNIEnv的RegisterNatives函数来完成JNI的注册数据类型的转换、基本数据类型的转换;基本数据类型转换除了最后一行的void,其他的数据类型只需要在前面加上j就可以了,第三列的Signature代表签名格式
  Java
  Native
  Signature
  byte
  jbyte
  B
  char
  jchar
  C
  boolean
  jboolean
  Z
  void
  void
  V
  引用数据类型的转换数组的JNI层数据类型需要以Array结尾,签名格式的开头都会有I;需要注意有些数据类型的签名以;结尾,引用数据类型还具有继承关系jclass、jstring、jarray和jthrowable都继承jobject,而jobjectArray、jintArray和jlongArray等类型都继承jarray尾述
  技术是无止境的,你需要对自己提交的每一行代码、使用的每一个工具负责,不断挖掘其底层原理,才能使自己的技术升华到更高的层面
  Android架构师之路还很漫长,与君共勉
  PS:有问题欢迎指正,可以在评论区留下你的建议和感受
  欢迎大家点赞评论,觉得内容可以的话,可以转发分享一下
投诉 评论 转载

使原子不可见的曲速驱动实验最终可以检验斯蒂芬霍金最著名的预测根据安鲁效应,一个以接近光速行进的加速物体应该被一群微弱发光的粒子包围(图片来源:EDUARDMUZHEVSKYI)一项新的曲速实验最终可以间接检验著名物理学家斯蒂芬霍金……荣耀80pro和荣耀70pro区别点在哪里,哪个好荣耀80pro和荣耀70pro区别有机身尺寸与颜色、续航以及充电速度、处理器、镜头,至于荣耀80pro和70pro哪个好,单配置来看,前者要好一些,但是作为拍照手机使用,这两者……莞港水运专线进出口总货值破千亿元央视网消息:年初以来,广东东莞开通的莞港水运专线,成为不少企业开展跨境运输业务的首选。12月8日,这条开通了289天的航线进出货值突破千亿元。今年,面对疫情对供应链带来的……恭喜!安东尼!再战一年早上收到的消息,安东尼和绿军已经坐下来准备签约了。双方的缘分,还要从加里纳利受伤说起,意大利炮为国出征,谁料一次无对抗上篮让他伤了半月板和十字韧带。队医预计起码也要伤退半个月,……Android系统由Java语言写很差吗?为什么按语言来要这JNI概述JNI(JavaNativeInterface,Java本地接口)是一种编程框架使得Java虚拟机中的Java程序可以调用本地应用或库,也可以被其他程序调用;本……威少确定留队,珍妮阿姨亲自拍板拒绝交易在休赛季,曾经传出湖人接近与步行者达成一笔重磅交易,用威少两个未来首轮换来希尔德特纳,甚至于拖延了湖人的新赛季发布会,最后这笔交易流产,外界普遍认为是湖人认为步行者要价太高而导……三次差一点,被命运捉弄的卡罗尔安迪。卡罗尔,利物浦球迷又爱又恨的球员。最近他历经的三次波折,足够精彩。正印证了周星驰电影《唐伯虎点秋香》里的经典台词人生的大起大落太快,实在太刺激啦。1。差一点被悔婚……平常心看待!百年大变局下的2022世界杯2022世界杯世界杯重回亚洲,卡塔尔世界杯在当下世界注定与众不同!首先中国以另一种方式参与成为全世界焦点,中国建设,中国制造,中国厂商赞助,中国烟花无人机表演让国人自豪,但也有……古人如何描绘伏儀与女娲的图片这是一张伏儀与女娲在乘坐宇宙飞船在星际航行的一张图片。尾部宇宙飞船形成的烟雾轨迹,身上穿的不是裙子,而是宇宙飞船的尾喷管。头顶上方是太阳。两侧是北斗星等星系。这张图片是在明显的……红薯见证父母的爱情故事头条创作挑战赛文依依三月的小山村,远远望去,朦胧的雾气萦萦绕绕,遮住了阳光。杨柳青青著地垂,杨花漫漫搅天飞。每年杨花漫漫舞时节,父母回到老家小山沟沟儿。县城的……华灿光电三季亏四千万,京东方拟捡漏入主!面板厂集体向上争夺M华夏时报(www。chinatimes。net。cn)记者卢晓北京报道尽管最近价格有所回暖的液晶面板才是本土面板厂商的营收主力,但下一代显示技术,永远是吊在前头、催促它们……寒冬时节,推荐安排六道营养炖菜,顺季而食身体好,暖心又暖胃大家好,这里是邱哥说美食,冬天是寒冷的季节,要说什么的美食最适合现在安排,要非热气腾腾的炖菜莫属了。炖菜,是全程大火炖煮出来的,热气腾腾,不用担心菜凉不好吃,一口下去,从头暖到……
云南大山里的小人国,身高不到一米三,背后有什么不为人知的故事美国西部自驾游16西雅图到旧金山不走寻常路太阳系最惨的行星鸡蛋鸭蛋鹅蛋鹌鹑蛋,哪种更营养?提醒3种蛋最好少吃附子药对(3)茵陈配附子之方剂介绍歌词复兴中华不是梦王者荣耀匹配机制解析,如何才能上分非全面屏版iOS动画细节一些肤浅的看法加密已热钱先知传统金融拥抱加密世界胃寒怕冷气血不足?小米加它煮粥喝,补气血暖脾胃,全身都暖了鄢陵模式从小清新到高大上飞跃发展的十年冬天,少吃萝卜白菜,多吃这2样,随手一蒸一炒,营养好吃不上火iPadOS15正式版来了,这8大实用功能告诉你该不该升级知乎CEO周源获得感是内容行业发展的最大公约数,知乎8。0全诉讼时效中断发生在哪些情况下?1岁半宝宝模仿爸爸痛风一瘸一拐,网友一个真痛风,一个学痛风中俄《尼布楚条约》究竟谁获益大?草鱼吃得多吗斤的草鱼一天吃多少草新能源汽车越来越受欢迎明年国内销量或达万辆为人谋划就是为己谋划宝鸡哪里的臊子面好吃?妈妈然我感动初中作文600字海尔热水器清洗(海尔电热水器怎么清洗和日常的保养维护)微信怎么查对对方具体在哪里?(原来微信还有这个隐藏功能)

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找七猫云易事利