Android开发之JNI基础知识

带着问题入场:

  • 什么是JNI,NDK, 与Java是什么关系,有什么应用场景?
  • JNI提供了哪些基本数据类型?

接下来会针对这两个问题,一一道来。

  1. 什么是JNI, NDK, 有什么应用场景?

    • JNI是Oracle提供的用于Java调用C/C++或C/C++调用Java的一套机制, 有自己的一套API,并且与C/C++或者汇编混合使用JNI,Java Native Interface,是 native code 的编程接口。JNI 使 Java 代码程序可以与 native code 交互——在 Java 程序中调用 native code;在 native code 中嵌入 Java 虚拟机调用 Java 的代码。

    • NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。这些工具对开发者的帮助是巨大的。

    • NDK集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出"哪些文件需要编译"、"编译特性要求"等),就可以创建出so.

    • NDK可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作.

    • 应用场景:

      • 可以将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率
      • 可以将需要保密的应用逻辑使用C开发。毕竟,Java包都是可以反编译的
      • 之前C/C++语言开发的基础功能模块复用到Android JNI环境下。
  2. JNI提供了哪些基本数据类型,提供了哪些API?

    • JNI基本数据类型与Java数据类型的对应关系

      basic_type_sign.png
    • JNI引用类型与Java数据类型的对应关系

      reference_type.png
    • 提供的特有的类, jfieldID, jmethodID, JNIEnv等

      1. jfielID 是JNI提供的JNI 字段类

      2. jmethodID 是JNI提供的JNI方法类

      3. JNIEnv是JNI 接口的全局指针类,类似于JNI的上下文对象

    • Global and Local References
      为啥会用到这两类引用?

      先说LocalReference,比如平时通过New操作得到的引用类型的对象,都属于Local Reference,看上去像是一个局部变量,其实不是,它与局部变量有这本质区别,在用完变量后需要手动释放,而局部变量却不需要。

      Global Reference 是全局的引用,在New Global后一定要Release 这个全局引用。

      关于这两类引用的使用过程中如何进行内存管理,在"JNI内存管理模型”中会详细描述。

    • 提供哪几类API,作用分别是什么?

      -- 类操作 FindClass()
      -- 全局引用与局部引用相关操作

        NewGlobalRef()
        DeleteGlobalRef()
        NewWeakGlobalRef()
        DeleteWeakGlobalRef()
        NewLocalRef()
        DeleteLocalRef()
      

      -- 对象操作 不知道有什么用?
      -- 访问对象的成员
      GetFieldID() Get<type>Field() 先拿fieldID,在获取字段值
      Set<type>Field()

      -- 访问静态成员
      GetStaticFieldID()
      GetStatic<type>Fiel SetStatic<type>Field
      -- 对象成员函数调用
      GetMethodID()
      Call<type>Method
      Call<type>MethodA
      Call<type>MethodV
      CallNonvirtual<type>Method
      CallNonvirtual<type>MethodA
      CallNonvirtual<type>MethodV
      -- 静态函数调用
      GetStaticMethodID()
      CallStatic<type>Method
      CallStatic<type>MethodA
      CallStatic<type>MethodV
      -- 字符串操作
      NewString() NewStringUTF()
      GetStringLength()
      GetStringChars()
      ReleaseStringChars()
      GetStringUTFLength()
      GetStringUTFChars()
      ReleaseStringUTFChars()
      GetStringRegion()
      GetStringUTFRegion()
      -- 数组操作
      GetArrayLength()
      NewObjectArray(JNIEnv *env, jsize length,jclass elementClass, jobject initialElement);
      jobject GetObjectArrayElement()
      SetObjectArrayElement()

       基本数据类型的数组操作
       New<PrimitiveType>Array()
       Get<PrimitiveType>ArrayElements()
       Release<PrimitiveType>ArrayElements(JNIEnv *env, ArrayType array, NativeType *elems, jint mode)
       参数对应关系图
       
       void Get<PrimitiveType>ArrayRegion(JNIEnv *env, ArrayType array,jsize start, jsize len, NativeType *buf);
       void Set<PrimitiveType>ArrayRegion(JNIEnv *env, ArrayType array,jsize start, jsize len, const NativeType *buf)
      

      -- 函数注册于反注册
      jint RegisterNatives(JNIEnv *env, jclass clazz,const JNINativeMethod *methods, jint nMethods);
      jint UnregisterNatives(JNIEnv *env, jclass clazz);
      -- 反射函数 还不知道如何使用
      jmethodID FromReflectedMethod(JNIEnv *env, jobject method);
      jfieldID FromReflectedField(JNIEnv *env, jobject field);
      jobject ToReflectedMethod(JNIEnv *env, jclass cls,jmethodID methodID, jboolean isStatic);
      jobject ToReflectedField(JNIEnv *env, jclass cls,jfieldID fieldID, jboolean isStatic);

    • JNI 类型签名

      • 基本数据类型的类型签名

        basic_type_sign.png
        • 引用数据类型的类型签名

          reference_type_sign.png
      • 方法的描述符

method_descriptor.png
  • JNI Exception

    • 三个函数ExceptionOccured(),ExceptionClear(),ThrownNew()。

    • 首先使用ExceptionOccured()函数判断是否发生异常,如果发生异常,可以在JNI处理也可以通过ThrowNew将异常抛出到Java层处理。但是在实际的使用中发现JNI的Exception有兼容性问题,不推荐使用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容