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层抛出异常

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android JNI学习路线可以按照以下步骤进行: 1. 了解JNI的基本概念和作用:JNIJava Native Interface)是Java提供的一种机制,用于实现Java与其他编程语言(如C、C++)之间的交互。它允许在Java代码中调用本地代码(Native Code),并且可以在本地代码中调用Java代码。 2. 学习JNI的基本语法和规则:JNI使用一组特定的函数和数据类型来实现Java与本地代码之间的交互。你需要学习如何声明本地方法、如何在Java代码中调用本地方法、如何在本地代码中调用Java方法等。 3. 学习JNI的数据类型映射:JNI提供了一套数据类型映射规则,用于将Java数据类型映射到本地代码中的数据类型。你需要学习如何处理基本数据类型、对象类型、数组类型等。 4. 学习JNI的异常处理:在JNI中,Java代码和本地代码之间的异常处理是非常重要的。你需要学习如何在本地代码中抛出异常、如何在Java代码中捕获异常等。 5. 学习JNI的线程处理:JNI允许在本地代码中创建和操作线程。你需要学习如何创建和销毁线程、如何在线程之间进行通信等。 6. 学习JNI的性能优化:JNI涉及到Java代码和本地代码之间的频繁切换,因此性能优化是非常重要的。你需要学习如何减少JNI调用的次数、如何避免不必要的数据拷贝等。 7. 学习JNI的调试和测试:在开发JNI程序时,调试和测试是非常重要的。你需要学习如何使用调试器调试本地代码、如何进行单元测试等。 8. 学习JNI的进阶主题:一旦掌握了基本的JNI知识,你可以进一步学习JNI的进阶主题,如JNIJava虚拟机的交互、JNI与动态链接库的交互、JNI与多线程的交互等。 总结起来,Android JNI学习路线包括了基本概念、基本语法、数据类型映射、异常处理、线程处理、性能优化、调试和测试以及进阶主题等内容。通过系统地学习这些知识,你将能够更好地理解和应用JNI技术。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值