ReactNativeforAndroid源码分析一《JNI智能指针之介绍篇》_第1页
ReactNativeforAndroid源码分析一《JNI智能指针之介绍篇》_第2页
ReactNativeforAndroid源码分析一《JNI智能指针之介绍篇》_第3页
ReactNativeforAndroid源码分析一《JNI智能指针之介绍篇》_第4页
ReactNativeforAndroid源码分析一《JNI智能指针之介绍篇》_第5页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、React Native for Android 源码分析 一 JNI 智能指针之介绍 篇React Native Android 源码分析 为了提高文章质量, 本 人决定周三 22.30(周六早 10.30 )定时推送技术相关文章, 对于方案相关的文章将不在其他渠道发出,只在公众号首发, 喜欢的朋友一定要记得哦! 导读React Native 发布以来将近一年多了, 也被抄的火爆到不行, 包括 RN 的中文网和各种资料也很多, 加之 SE5 ,SE6 语法 升级,学习成本并不在于 RN 环境搭建和入门,关键还是对JS的入门掌握,无论你是用Native移动开发,H5前端开发, 还是 React

2、 Native 的开发,都应该明白上层语言和底层交互, 都离不开 C, 今天就介绍下 native 中 Jni 过程中的指针运用。 文章适合已经入门了 RN 的朋友看, 推荐入门资料: Android 开发者转 React Native 必看教程汇总。JNI 指针通常的 app 中, JNI 提供的 native 函数主要充当 Java 类的扩 展,逻辑层在 Java 端, JNI 端较少使用 OOP 的设计思想。 而对于 native 端功能较重的模块,例如开源的阅读器FBReader , native 端与 Java 端有较多交互, 即 native 会主 动创建 Java 对象并调用它们

3、的方法以实现功能,这时就需要考虑将 native 至 Java 的操作与访问框架化,形成更高层 次的封装,以避免直接使用原始的 JNI 反射 API 集去操作 Java 对象。对于 ReactNative For Android 而言,这套访问框架尤其重要, 其核心就是 JNI 智能指针这个基本数据类型。它的实现基于 C11 标准,将先用几篇对这套 native 至 Java 的操作框架进 行介绍,为后续分析打下良好基础。 JNI 指针 通常的 app 中 , JNI 提供的 native 函数主要充当 Java 类的扩 展,逻辑层在 Java 端, JNI 端较少使用 OOP 的设计思想。

4、而对于 native 端功能较重的模块,例如开源的阅读器 FBReader ,native 端与 Java 端有较多交互, 即 native 会主 动创建 Java 对象并调用它们的方法以实现功能,这时就需 要考虑将 native 至 Java 的操作与访问框架化,形成更高层 次的封装,以避免直接使用原始的 JNI 反射 API 集去操作 Java 对象。对于 ReactNative For Android 而言,这套访问框架尤其重要, 其核心就是 JNI 智能指针这个基本数据类型。它的实现基于 C11 标准,将先用几篇对这套 native 至 Java 的操作框架进 行介绍,为后续分析打下良

5、好基础。 Native 引用 首先回顾一下 Java Object ( jobject )在 native 端的三种引 用类型:全局引用类似于 C 语言中的全局变量。使用 NewGlobalRef 创建,支持跨线程访问 ,在调用释放DeleteGlobalRef 销毁前, GC 无法回收该引用对应的 java object 。局部引用 概念上与 C 语言中的局部变量有相似点, 但不等同。 使用 NewLocalRef 创建 , 只能在本线程内安全访 问,当创建该引用的 native 调用链返回至 JVM 时,未销毁 的局部引用会被 JVM 自动 GC 回收。但由于局部引用表容 量有限,在返回至

6、 JVM 前,可以调用 DeleteLocalRef 先行 销毁,避免局部引用表超限引起崩溃。弱全局引用与全局引 用一样具有全局作用域, 但不会影响 GC 回收 , GC 可以随时 回收该引用对应的 java object 。使用 NewWeakGlobalRef 创建,当需要使用时,需要将其升级为全局引用或者局部引 用,若已被回收,会返回 null ,使用 DeleteWeakGlobalRef 销毁。该引用类型使用场景较少。由上可见, JNI 智能指针 的第一个需求, 就是要自动管理 jobject 的生命周期, 当进入 与离开对应作用域时,需要自动调用对应生命周期的创建与 销毁函数。这在

7、 C+ 中,通常会结合构造与析构函数来进行 配对调用。 若功能仅限于此, 就与普通的智能指针和 mutext 锁管理机制类似了, 更重要的需求是在 C+ 层提供与被管理 的 Java 对象镜像结构的 C+ 对象 , 形成高层次封装。这样, 对 jobject 的访问与操作就会被封装在对应的镜像 C+ 对象 中,相关 JNI 反射调用的细节被隐藏,对于其他 native 模块 而言,与 Java 层的交互被转化成了与这些镜像 C+ 对象的 交互,整个实现风格 OOP 化了。这些镜像 C+ 对象被称为 wrapper 对象,其定义代码位于 ReactAndroid/src/main/jni/fir

8、st-party/fb/include/fb/fbjni/Cor eClasses.h 文件中。先看一个使用范例: struct MyClass : public JavaClass<MyClass> constexpr static auto kJavaDescriptor = Lcom/example/package/MyClass; void foo() static auto method = javaClassStatic()->getMethod<void()>(foo);method(self(); static local_ref<javao

9、bject> create(int i) return newInstance(i);auto obj = MyClass:create(10);obj->foo();Native 的需求是在 native 端创建 com.example.package.MyClass 这个自定义的 Java 类的对 象,并访问它的 foo 方法。实现步骤 例子中实现的步骤是: 定义 java 的 MyClass 的 wrapper C+ 类 MyClass ,所有 wrapper 均需要继承于 JavaClass 的一个 模板实例, 并将自身类型做为 JavaClass 的第一个模板类型 参数

10、,以供 JavaClass 获取具体 wrapper 的类型。给 static 成员变量 kJavaDescriptor 赋值为对应 Java 类的全类名。 在 wrapper 类实现镜像方法 foo(), 其会获取 jclass 的包装类 JClass 对象,并获取 jmethod 的包装类 JMethod 进行调用。 create 工厂方法中使用 newInstance 构建镜像对象的实例, 并将其存至局部智能指针 local_ref<javaobject> 。这样 就可以通过智能指针访问 wrapper class 提供的 foo 方法, 实现了 native 至 Java

11、的镜像映射。 除了实现对一个 java 类 的的映射,还需要支持对 java 继承关系的映射。若 java 的 MyClass 有一子类 MyChildClass , native 层为其建立的 wrapper class 可如下: struct MyChildClass : public JavaClass<MyChildClass, MyClass> constexpr static auto kJavaDescriptor = Lcom/example/package/MyChildClass;这里需要用到 JavaClass 的第二个模板参数, 设为 MyClass , 它

12、是 JavaClass<MyChildClass, MyClass> 这个模板实 例的父类型。 通过构造这样的继承链, MyChildClass 获得了 父类 MyClass 提供的 java 方法映射,完成了继承关系在 native 层的映射。上面例子中, 返回的 obj 可以调用 wrapper 提供的镜像方法, 应可以看出,智能指针存放的并不是原始的 jobject ,而是更 抽象的 wrapper MyClass 对象。与通常的智能指针不一样, local_ref 局部指针的模板参数并不直接指代其存储值的类型。 在上面代码中, obj 的类型除了根据 create 函数签名

13、推导出 的 local_ref<MyClass:javaobject>, 也可以写成 local_ref<MyClass> ,这两者是等价的。若 native 端只 需要保存 jobject ,不需直接调用 wrapper 类的方法, 也可以 使用 local_ref<jobject> 。疑问 这就带来几个问题: javaObject 与 jobject 的关系是什么?为 什么智能指针的模板参数能够接受多种类型?模板参数起 到的作用是什么? 结尾 这些问题将在下一篇智能指针的具体实现篇中解答。 综上介绍,在 ReactNative for Android 中,为了简化 Native 层对 Java 层的调用,提供了镜像结构的 wrapper class ,结 合智能指针,将 jobject

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论