zoukankan      html  css  js  c++  java
  • Android深入理解JNI

    一、JNI概述

    JNI是Java Native Interface的缩写,中文译为“Java 本地调用”。通俗地说,JNI是一种技术,通过这种技术可以做到以下两点:

    Java程序中的函数可以调用Native语言写的函数,Nativie一般指的是C/C++编写的函数。

    Native程序中的函数可以调用Java层的函数,也就是说在C/C++程序中可以调用Java函数。

    在平台无关的Java中,为什么要创建一个与Native相关的JNI技术呢?这岂不是破坏了Java的平台无关特性吗?JNI技术的推出有以下几个方面的考虑。

    承载Java世界的虚拟机是Native语言写的。而虚拟机又运行在具体的平台上,所有虚拟机本身无法做到平台无关。然而,有了JNI技术后就可以对Java层屏蔽不同的操作系统平台之间的差异了。这样,就能实现Java本身的平台无关特性。其实Java一种使用JNI技术,只是我们平时较少用到罢了。

    早在Java语言诞生前,很多程序都是用Native语言写的,它们遍布在世界各地。Java出世后,它受到了追捧,并迅速得到发展,但仍无法将软件世界彻底改朝换代,于是才有了折中的办法。既然已经有Native模块实现了相关功能,那么在Java中通过JNI技术直接使用它们就行了,防止重复造轮子。

    在Android平台上,JNI就是一座将Native世界和Java世界间相连接的桥梁。

    二、学习JNI的实例:MediaScanner

    由于Android大量使用了JNI技术,本章接下来的内容就将源码中的一处实例来讲解JNI相关的知识。

    Java(MediaScanner)——》JNI(libmedia_jni.so)——》Native(libmedia.so)

    Java世界对应的是MediaScanner,而这个MediaScanner类有一些函数需要由Native层来实现。

    JNI层对应的是libmedia_jni.so。media_jni是JNI库的名字,其中,下划线前的“media”是Native层库的名字,这里就是libmedia库。下划线后的“jni”表示它是一个JNI库。注意,JNI库的名字可以随便取,不过Android平台基本上都采用“lib模块名_jni.so”命名的方式。

    Native层对应的是libmedia.so,这个库完成了实际的功能。

    Media 

    Java层的MediaScanner分析

    先来看MediaScanner的源码,这里将提取出与JNI相关的部分

    加载JNI库

    前面说过,如果Java要调用native函数,就必须通过一个位于JNI层的动态库来实现。顾名思义,动态库就是运行时加载的库,那么在什么时候以及什么地方加载这个库呢?

    这个问题没有标准答案,原则上是:在调用native函数前,任何时候、任何地方加载都可以。通行的做法是在类的static语句中加载,调用System.loadLibrary方法就可以了。

    这一点在上面的代码也见到了。另外,System.loadLibrary函数的参数是动态库的名字,即media_jni。系统会自动根据不同的平台扩展成真实的动态库文件名,例如在Linux系统上会拓展成libmedia_jni.so,而在Window平台上就会拓展成media_jni.dll。

    解决了JNI库加载的问题

    Java的native函数和总结

    从上面代码中可以发现,native_init和processFile函数前都有Java的关键子native,它表示这两个函数将由JNI层来实现。

    Java层的分析到此结束。JNI技术也很照顾Java程序员,只要完成下面两项工作就可以使用JNI了:

    加载对应的JNI库

    声明由关键字native修饰的函数

    所有,对于Java程序员来说,使用JNI技术真的是太容易了。不过JNI层要完成任务可没那么轻松,下面来看对JNI层的MediaScanner的分析

    2.4JNI层MediaScanner的分析

    注册JNI函数

    正如代码中注释的那样,native_init函数对应的JNI函数是android_media_MediaScanner_native_init,可能细心的读者要问了,你怎么知道native函数对应的是这个JNI函数,而不是其他的呢?莫非是根据函数的名字来确定的?

  • 相关阅读:
    Android笔记:数据储存
    Android笔记:管理所有活动
    Android随笔:属性
    Android笔记:限定符
    Android笔记:ninepatch
    Android笔记:获取屏幕信息
    js自动完成
    动态生成实体类
    EF框架学习手记
    js遮罩效果
  • 原文地址:https://www.cnblogs.com/riyueqian/p/15715655.html
Copyright © 2011-2022 走看看