美文网首页
JNI开发——基本实现

JNI开发——基本实现

作者: 追寻米K | 来源:发表于2018-10-10 23:09 被阅读0次

    jni 全名是java native interface。

    JNI资料

    什么时候使用JNI:

           1、 java api 不能满足程序需要的时候

            2、要求性能比较高的时候,算法的计算,图像的渲染等。

            3、当需要访问已有的本地库的时候

    开发步骤:

            1、编写native方法。

            2、javah生成 .h 头文件

            3、复制 .h文件到cpp目录。

            4、实现.h头文件中的声明函数。

    1、写个hello world:

    C代码:

    java代码:

    C 中env是一个结构体二级指针。

    上面是静态的java方法,现在用一个非静态的方法:

    java代码:

    C代码:

    静态方法和非静态方法除了调用的时候不一样之外在C代码里面只有jclass和jobject这一个参数的不同。

    JNI的基本数据类型:

    jboolean、jbyte、jchar、jshort、jint、jlong、jfloat、jdouble

    引用类型:字符 jstring  其他都是object;

    数组:jByteArray   公式:jTypeArray;

    引用类型数组:都是jobjectArray;

    java方法的签名

    如:void a(int b)  签名就是"(I)V"

    String gets() 签名是"()Ljava/lang/String;"

    其他类型如Bitmap 就是"Ljava/lang/Object"

     对于数组,其为 :  [ + 其类型的域描述符 + ;

                      int[ ]     其描述符为[I

                      float[ ]   其描述符为[F

                      String[ ]  其描述符为[Ljava/lang/String;

                     Object[ ]类型的域描述符为[Ljava/lang/Object;

              多维数组则是 n个[ +该类型的域描述符 , N代表的是几维数组。例如:

                 int  [ ][ ] 其描述符为[[I

                float[ ][ ] 其描述符为[[F

    2、c访问java中的非静态域:

    C的代码:

    java的代码:

    显示结果:miK简单的JNI。

    错误一:不要直接strcat(text,c_str),因为text有存储“简单JNI”这几个字符的空间,后面拼接的字符存不下,可以使用数组 char[50] text。

    错误二的写法:

    显示结果:miK

    new 了一个mainActivity的新对象 修改了这个对象中的key值,并没有修改当前mainactivity中的key值。

    3、c访问java中的静态域:

    C代码:

    java 代码:

    输出结果:11。

    也就是C方法上多了一个static。

    4、c调用java的非静态方法:

    C代码:

    java代码:

    输出结果就是随机的整数。

    5、c调用java的静态方法:

    c代码:

    java代码:

    输出结果就是一串字符串。

    6、c调用java的构造方法:

    c代码:

    java代码:

    输出结果:

    7、JNI字符串乱码问题:

    java使用utf-16的编码方式(16bit),中英文都是用2个字节

    jni中使用utf-8的编码方式,英文是一个字节,英文三个字节

    C/C++英文使用ASCII编码方式,中文使用GB2312编码方式,两个字节表示一个汉字。

    android studio 右下角默认utf-8的编码方式,所以没有EC上的乱码

    8、GetStringUTFChars(env, j_str,NULL)第三个参数的问题说明:

    输出的日志:iscp = JNI_TRUE。所以第三个参数是取值,不是传值。java的string在是否内存中复制了一份给C使用,可以通过这个判断是否回收释放。

    9、访问java基本类型的数组:

    c代码:

    java代码:

    输出结果:

    10、访问java引用类型数组:

    c代码:

    java代码:

    输出结果:

    11、JNI的引用:

    局部引用:

    全局引用:

    弱全局引用:

    12、JNI异常处理:

    在java中就可以try  catch 捕获了

    13、JNI缓存:

    局部静态变量缓存:

    C代码:

    java代码:

    只打印了一次“javaKey”,如果把static去掉就会打印多次。

    存储在静态区,只需定义并初始化一次,之后一直有。

    全局静态缓存:

    全局使用这个变量只能在定义之后的方法里使用

    14、动态注册:

    java代码:

    FileUtils:

    C代码:

    JNI_Onload方法由系统调用,具体在哪调用下一篇JNI原理会有。

    静态注册:

    1、每个class都需要使用javah生成一个头文件,并且生成的名字很长书写不便;

    2、初次调用时需要依据名字搜索对应的JNI层函数来建立关联关系,会影响运行效率

    3、用javah 生成头文件方便简单

    动态注册:

    1、使用一种数据结构JNINativeMethod来记录java native函数和JNI函数的对应关系

    2、移植方便(一个java文件中有多个native方法,java文件的包名更换后)

    相关文章

      网友评论

          本文标题:JNI开发——基本实现

          本文链接:https://www.haomeiwen.com/subject/zuvxlftx.html