我是靠谱客的博主 美满斑马,最近开发中收集的这篇文章主要介绍JNI理解学习,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

学习自深入理解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理解学习所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部