• 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 CallMethod(JNIEnv *env,jobject obj,jmethodID id,...)

    type对应java函数的返回值类型,如CallIntMethod,CallVoidMethod

    若调用java中的static函数,则用CallStaticMethod

     JNIEnv的一系列操作jfildID函数

    NativeType getField(JNIEnv *env,jobject obj,jfildID id)

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

  • 相关阅读:
    Vue 指令整理
    ASM3142 USB 3.1控制芯片_ ASM3242 USB 3.2 2x2 控制器
    java web 前置知识——Servlet(一)
    HashMap 源码解读(JDK1.8)
    gitblit git pycharm 新建版本库及push备忘
    Meta因露骨AI图片陷入困境
    高效防汛决策:山海鲸可视化系统助力城市防洪
    DBCO-PEG-carboxyl COOH-PEG-DBCO 二苯并环辛炔-聚乙二醇-羧酸 羧酸修饰PEG二苯并环辛炔
    MySQL日志系列(1):MySQL日志
    基于SSM的校园二手物品交易市场设计与实现
  • 原文地址:https://blog.csdn.net/somethingstill/article/details/106660527