概述
学习自深入理解Android卷一
jni中文java本地调用,通过这种技术可以做到:
a、java程序中的函数可以调用native语言写的函数,native一般是指C、C++编写的函数
b、native中的函数可以调用java层的函数
Android平台上的jni:
学习jni的实例:MediaScanner
在何时加载jni库,没有具体的标准,只要在使用native函数前,任何时候,任何地方都可以加载jni库,通常的做法是在类的static语句中加载
函数注册
静态方法
注册函数对应
JNI数据类型转换表
JNIEnv
JavaVm和JNIEnv的关系:
javaVm在jni_onLoad中,一个java进程中只有一个javaVM
JNIEnv如何操作object:java的应用类型,大部分在jni层都会用jobject来表示对象的数据类型,一个java对象的组成是由成员变量和成员函数组成,操作java的object的本质就是操作这些对象的成员变量和成员函数
jfildID成员变量
jmethodID成员函数
JNIEnv输出了一系列的操作jMethod函数
NativeType Call<type>Method(JNIEnv *env,jobject obj,jmethodID id,...)
type对应java函数的返回值类型,如CallIntMethod,CallVoidMethod
若调用java中的static函数,则用CallStatic<type>Method
JNIEnv的一系列操作jfildID函数
NativeType get<type>Field(JNIEnv *env,jobject obj,jfildID id)
NativeType set<type>Field(JNIEnv *env,jobject obj,jfildID id, NativeType value)
jstring虽然也是java中的引用类型,但是使用频率很高,所以jni单独创建了一个jstring类型
jni中操作jstring的主要函数
JNIEnv:
a、NewString(JNIEnv *env , const jchar *unicodeChars, jsize len) 从native字符串得到一个jstring对象
b、NewStringUTF根据native的一个UTF-8字符串得到一个jstring对象
c、GetStringChars函数和GetStringUTFChars函数,可以将java String对象转换成本地字符串,GetStringChars得到一个Unicode字符串,GetStringUTFChars得到一个UTF-8字符串
d、调用了以上函数,在工作完成后,都需要调用ReleaseStringChars或者ReleaseStringUTFChars来对应的释放本地资源
JNI签名信息:
签名是由java层对应函数的参数类型和返回值类型组成,原因是java支持重载,可以定义同名但不同参数的函数,JNI根据函数名是无法找到具体的函数,所以将参数类型和返回值类型组合作为一个函数的签名信息
返回值的类型标识:
例如:
java函数 String fun() -----------------对应的JNI函数 “()Ljava/lang/String”
java函数 String fun(int i,Class b) -----------------对应的JNI函数 “(I;Ljava/lang/object)Ljava/lang/String”
JNI提供了三种类型的引用:
a、Local Reference:本地引用,在jni层使用的非全局引用都是本地引用,包括函数调用时传入的jobject和jni层函数中创建的jobject,本地引用的特点是,一旦jni函数返回,这些jobject就可能被垃圾回收,类似java的局部变量
b、Global Reference:全局引用,不主动释放,永远不会被垃圾回收,比java的全局变量更持久
c、Weak Global Reference:弱全局引用,在运行过程中可能被回收,在使用前要用JNIEnv的IsSameObject判断是否被回收
注意Local Reference
本来local reference在函数完成后,pathStr会自动回收,看起来deleteLocalRef(pahtStr)是多余的:
1、如果不调用deleteLocalRef,在函数执行完成后,pathStr会被回收
2、如果调用deleteLocalRef,pathStr会被立即回收,看起来没什么区别,但是如果是以下这种情况
for(int i=0; i<100; i ++){
jstring pathStr = jniEnv->NewStringUTF(path);
......
jniEnv->DeleteLocalRef(pathStr); //如果不立即释放pathStr,会创建100个jstring
}
所以一定要在对应的地方,及时的释放
JNI异常处理
jniEnv提供了三个函数来捕获和处理异常:
a、ExceptionOccured函数用来判断是否发生异常
b、ExceptionClear函数,用来清理当前JNI中发生的异常
c、ThrowNew函数,用来向java层抛出异常
最后
以上就是美满斑马为你收集整理的JNI理解学习的全部内容,希望文章能够帮你解决JNI理解学习所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复