现在的位置: 首页 > 综合 > 正文

JNI学习(1)(我是菜鸟)

2013年08月26日 ⁄ 综合 ⁄ 共 2208字 ⁄ 字号 评论关闭

所有内容为记录学习过程,不是大牛尽情谅解。所有分析都参考深入理解Android 卷一

概括:

Android平台上,JNI就是一座将Native世界和Java世界间的天堑变为通途的桥。

JAVA  <---> JNI <---> NATIVE

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

JNI层对应的是libmedia_ni.so库 media_jniJNI库的名字,其中,下划线前的mediaNative层库的名字。

Android平台上基本采用lib模块名_jni.so的命名方式

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

MediaScanner 将通过JNI库 libMedia_jni.soNative

现在看代码

frameworks/base/media/java/android/media/MediaScanner.java

加载对应的JNI库,media_jniJNI库名,在实际加载的时候拓展成libmedia_jni.so,在windows平台上扩展为media_jni.dll

Native函数的声明

现在看一下 native_init();函数 

framewords/base/media/jni/android_media_MediaScanner.cpp

这部分为MediaScannerJNI代码

到这里有个问题native_init 怎么就映射成了android_media_MedeaScanner_native_init

仔细查看 native_init 函数 位于android.media这个包中MediaScanner.java这个问题中

这么一看思路就有点对了

android.media.MediaScanner.native_init 将这里面的.(点)换成下划线就对应上了。

因为在native语言中,”.”符号点有着特殊的含义,所以JNI 层需要把java函数名称(包括包名)中的”.”换成”_” 也就是通过这种方式native_init 找到了自己的另一半android.;mediaMediaScanner.native_init

可以看出 静态方法就是根据函数名来建立 java函数和JNI函数的关联关系的,这个关联关系由虚拟机完成

下面看一下JNI 中的动态注册

Java native 函数 和JNI 函数 是一一对应的,其对应该系用一个结构来保存。

JNINativeMethod的结构
type struct{

const char* name;//java中的native函数的名称,不用携带包路径,例如 native_init

const char* signature;//函数签名信息,用字符串表示,是参数类型和返回值类型的组合

void* fnPtr;//JNI层对应函数的函数指针,void*类型

} JNINativeMethod;

应该如何使用这个结构体呢,看一下MediaScanner JNI 层的做法



register_android_media_MediaScanner(JNIEnv *env)函数

调用AndroidRuntime::registerNativeMethods();

完成JNI函数的注册问题

Frameworks/base/core/jni/AndroidRuntime.cpp

Dalvik/libnativehelper/JNIHelp.c

其实这里面只用两个操作就完成了 注册

第一个是获取android/media/MediaScanner 类 

另一个 就是将刚才JNINativeMethod 里面注册的方法和这个获取的类绑定

为了学习JNI中的数据类型转换,这里看一下processFile这个函数





MediaScanner.java中的定义 

Private native void processFile(String path, String mimeType, MediaScannerClient client)

对应的android_media_MediaScanner.cpp

Static void android_media_MediaScanner_processFile(JNIEnv *env,jobject thiz, jstring path,

Jstring mimetype, jobject client)

Java中的String 对应 JNI 中的jstring

Java中的MediaScannerClient 对应JNI中的jobject

如果都用jobject表示,那么该如何操作呢。

解释一下JNI层中几个函数参数的意义

第一个JNIEnv 是一个 JAVA环境,对于这个变量,暂时没明白,以后分析。

第二个jobject 由于是非静态方法所以传过来的是MediaScanner对象,它表示是安格MediaScnner对象上调用了processFile (如果该函数在java层定义为static寒素那么这个参数就换位jclass 表示在哪个class中调用了该静态方法 这个应该很容易理解)

下面就开始 JNIEnv介绍了

下面开始jstring介绍

下面开始JNI类型签名介绍

下面开始垃圾回收介绍

下面开始JNI异常介绍


抱歉!评论已关闭.