ReactNative 4Android源码分析二JNI智能指针.doc

ReactNative 4Android源码分析二JNI智能指针.doc

  1. 1、本文档共10页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
ReactNative 4Android源码分析二JNI智能指针

ReactNative 4Android源码分析二: JNI智能指针 《JNI智能指针之介绍篇》: JNI指针 通常的app中, JNI提供的native函数主要充当Java类的扩展,逻辑层在Java端,JNI端较少使用OOP的设计思想。 而对于native端功能较重的模块,例如开源的阅读器FBReader,native端与Java端有较多交互,即native会主动创建Java对象并调用它们的方法以实现功能,这时就需要考虑将native至Java的操作与访问框架化,形成更高层次的封装,以避免直接使用原始的JNI反射API集去操作Java对象。 对于ReactNative For Android而言,这套访问框架尤其重要,其核心就是JNI智能指针这个基本数据类型。它的实现基于C11标准,将先用几篇对这套native至Java的操作框架进行介绍,为后续分析打下良好基础。 Native引用 首先回顾一下Java Object(jobject)在native端的三种引用类型: 全局引用 类似于C语言中的全局变量。使用NewGlobalRef创建,支持跨线程访问 ,在调用释放DeleteGlobalRef销毁前,GC无法回收该引用对应的java object。 局部引用 概念上与C语言中的局部变量有相似点,但不等同。使用NewLocalRef创建, 只能在本线程内安全访问,当创建该引用的native调用链返回至JVM时,未销毁的局部引用会被JVM自动GC回收。但由于局部引用表容量有限,在返回至JVM前,可以调用DeleteLocalRef先行销毁,避免局部引用表超限引起崩溃。 弱全局引用 与全局引用一样具有全局作用域,但不会影响GC回收, GC可以随时回收该引用对应的java object。使用NewWeakGlobalRef创建,当需要使用时,需要将其升级为全局引用或者局部引用,若已被回收,会返回null,使用DeleteWeakGlobalRef销毁。该引用类型使用场景较少。 由上可见,JNI智能指针的第一个需求,就是要自动管理jobject的生命周期,当进入与离开对应作用域时,需要自动调用对应生命周期的创建与销毁函数。这在C++中,通常会结合构造与析构函数来进行配对调用。若功能仅限于此,就与普通的智能指针和mutext锁管理机制类似了,更重要的需求是在C++层提供与被管理的Java对象镜像结构的C++对象,形成高层次封装。这样,对jobject的访问与操作就会被封装在对应的镜像C++对象中,相关JNI反射调用的细节被隐藏,对于其他native模块而言,与Java层的交互被转化成了与这些镜像C++对象的交互,整个实现风格OOP化了。这些镜像C++对象被称为wrapper对象,其定义代码位于ReactAndroid/src/main/jni/first-party/fb/include/fb/fbjni/CoreClasses.h文件中。 先看一个使用范例: struct MyClass : public JavaClassMyClass { constexpr static auto kJavaDescriptor = Lcom/example/package/MyClass;; void foo() { static auto method = javaClassStatic()-getMethodvoid()(foo); method(self()); } static local_refjavaobject 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的第一个模板类型参数,以供JavaClass获取具体wrapper的类型。 给static成员变量kJavaDescriptor赋值为对应Java类的全类名。 在wrapper类实现镜像方法foo(), 其会获取jclass的包装类JClass对象,并获取jmethod的包装类JMethod进行调用。 create工厂方法中使用newInstance构建镜像对象的实例,并将其存至局部智能指针local_ref。这样就可以通过智能指针访问wrapper class提供的

文档评论(0)

shuwkb + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档