React Native 4 for Android源码分析 一《JNI智能指针之介绍篇》
文/ Tamic: http://www.52php.cn/article/p-pbgotwkp-bee.html 导读React Native 发布以来将近一年多了,也被抄的火爆到不行,包括RN的中文网和各种资料也很多,加之SE5,Se6语法升级,学习成本并不在RN环境搭建和入门,关键还是对JS的掌握入门,不管你是用Native开发,h5开发,还是React Native的开发,都应该明白上层语言和底层交互,都离不开c, 今天就介绍下native中Jni过程中的指针运用。文章适合入门了RN的朋友看,入门资料:Android 开发者转 React Native 必看教程汇总 JNI指针通常的app中,JNI提供的native函数主要充当Java类的扩展,逻辑层在Java端,JNI端较少使用OOP的设计思想。 而对于native端功能较重的模块,例如开源的阅读器FBReader,native端与Java端有较多交互,即native会主动创建Java对象并调用它们的方法以实现功能,这时就需要考虑将native至Java的操作与访问框架化,形成更高层次的封装,以避免直接使用原始的JNI反射API集去操作Java对象。 Native引用首先回顾一下Java Object(jobject)在native端的三种引用类型: 全局引用 类似于C语言中的全局变量。使用NewGlobalRef创建,支持跨线程访问 ,在调用释放DeleteGlobalRef销毁前,GC无法回收该引用对应的java object。 局部引用 概念上与C语言中的局部变量有相似点,但不等同。使用NewLocalRef创建,只能在本线程内安全访问,当创建该引用的native调用链返回至JVM时,未销毁的局部引用会被JVM自动GC回收。但由于局部引用表容量有限,在返回至JVM前,可以调用DeleteLocalRef先行销毁,避免局部引用表超限引起崩溃。 弱全局引用 与全局引用一样具有全局作用域,但不会影响GC回收,GC可以随时回收该引用对应的java object。使用 由上可见,JNI智能指针的第一个需求,就是要自动管理jobject的生命周期,当进入与离开对应作用域时,需要自动调用对应生命周期的创建与销毁函数。这在C++中,通常会结合构造与析构函数来进行配对调用。若功能仅限于此,就与普通的智能指针和mutext锁管理机制类似了,更重要的需求是在C++层提供与被管理的Java对象镜像结构的C++对象,形成高层次封装。这样,对jobject的访问与操作就会被封装在对应的镜像C++对象中,相关JNI反射调用的细节被隐藏,对于其他native模块而言,与Java层的交互被转化成了与这些镜像C++对象的交互,整个实现风格OOP化了。这些镜像C++对象被称为wrapper对象,其定义代码位于 先看一个使用范例: 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<javaobject> 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类的全类名。 create工厂方法中使用newInstance构建镜像对象的实例,并将其存至局部智能指针local_ref。这样就可以通过智能指针访问wrapper class提供的foo方法,实现了native至Java的镜像映射。 除了实现对一个java类的的映射,还需要支持对java继承关系的映射。若java的MyClass有一子类MyChildClass,native层为其建立的wrapper class可如下: struct MyChildClass : public JavaClass<MyChildClass,MyClass> { constexpr static auto kJavaDescriptor = "Lcom/example/package/MyChildClass;"; }; 这里需要用到JavaClass的第二个模板参数,设为MyClass,它是JavaClass 疑问这就带来几个问题: javaObject与jobject的关系是什么? 为什么智能指针的模板参数能够接受多种类型? 模板参数起到的作用是什么? 结尾这些问题将在下一篇智能指针的具体实现篇中解答。 Tamic: http://blog.csdn.net/sk719887916/ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |