PS:该文章仅供个人学习交流之用,不当之处,还请指出,欢迎拍砖吐槽!
一.React Native 框架分析
层次架构:
Java层:该层主要提供了Android的UI渲染器UIManager(将JavaScript映射成Android Widget)以及一些其他的功能组件(例如:Fresco、Okhttp)等,在java层均封装为Module,java层核心jar包是react-native.jar,封装了众多上层的interface,如Module,Registry,bridge等。
C++层:主要处理Java与JavaScript的通信以及执行JavaScript代码工作,该层封装了JavaScriptCore,执行对js的解析。基于JavaScriptCore,Web开发者可以尽情使用ES6的新特性,如class、箭头操作符等,而且 React Native运行在JavaScriptCore中的,完全不存在浏览器兼容的情况。Bridge桥接了java , js 通信的核心接口。JSLoader主要是将来自assets目录的或本地file加载javascriptCore,再通过JSCExectutor解析js文件。
Js层:该层提供了各种供开发者使用的组件以及一些工具库。
Component:Js层通js/jsx编写的Virtual Dom来构建Component或Module,Virtual DOM是DOM在内存中的一种轻量级表达方式,可以通过不同的渲染引擎生成不同平台下的UI。component的使用在 React 里极为重要, 因为component的存在让计算 DOM diff 更高效。
ReactReconciler : 用于管理顶层组件或子组件的挂载、卸载、重绘。
注:JSCore,即JavaScriptCore,JS解析的核心部分,IOS使用的是内置的JavaScriptCore,Androis上使用的是 https://webkit.org 家的jsc.so。
Java层核心类及原理,如下所示:
ReactContext
ReactContext继承于ContextWrapper,是ReactNative应用的上下文,通过getContext()去获得,通过它可以访问ReactNative核心类的实现。
ReactInstanceManager
ReactInstanceManager是ReactNative应用总的管理类,创建ReactContext、CatalystInstance等类,解析ReactPackage生成映射表,并且配合ReactRootView管理View的创建与生命周期等功能。
ReactRootView
为启动入口核心类,负责监听及分发事件并重新渲染元素,App启动后,其将作为App的root view。
CatalystInstance
CatalystInstance是ReactNative应用Java层、C++层、JS层通信总管理类,总管Java层、JS层核心Module映射表与回调,三端通信的入口与桥梁。
JavaScriptModule
JavaScriptModule是JS Module,负责JS到Java的映射调用格式声明,由CatalystInstance统一管理。
NativeModule
NativeModule是ava Module,负责Java到Js的映射调用格式声明,由CatalystInstance统一管理。
JavascriptModuleRegistry
JS Module映射表,负责将所有JavaScriptModule注册到CatalystInstance,通过Java动态代理调用到Js。
NativeModuleRegistry
是Java Module映射表,即暴露给Js的API集合。
CoreModulePackage
定义核心框架模块,创建NativeModules&JsModules。
启动过程的解析:
1.ReactInstanceManager创建时会配置应用所需的java模块与js模块,通过ReactRootView的startReactApplication启动APP。
2.在创建ReactInstanceManager同时会创建用于加载JsBundle的JSBundlerLoader,并传递给CatalystInstance。
3.CatalystInstance会创建Java模块注册表及Javascript模块注册表,并遍历实例化模块。
4.CatalystInstance通过JSBundlerLoader向Node Server请求Js
Bundle,并传递给JSCJavaScriptExectutor,最后传递给javascriptCore,再通过ReactBridge通知ReactRootView完成渲染。
Js与Java通信机制
Java与Js之间的调用,是以两边存在两边存在同一份模块配置表,最终均是将调用转化为{moduleID,
methodID,callbackID,args},处理端在模块配置表里查找注册的模块与方法并调用。
1. Java 调用Js
Java通过注册表调用到CatalystInstance实例,透过ReactBridge的jni,调用到Onload.cpp中的callFunction,最后通过javascriptCore,调用BatchedBridge.js,根据参数{moduleID,methodID}require相应Js模块执行。流程如下图:
1. Js 调用Java
如果消息队列中有等待Java 处理的逻辑,而且 Java 超过 5ms 都没有来取走,那么 JavaScript 就会主动调用 Java 的方法,在需要调用调Java模块方法时,会把参数{moduleID,methodID}等数据存在MessageQueue中,等待Java的事件触发,把MessageQueue中的{moduleID,methodID}返回给Java,再根据模块注册表找到相应模块处理。流程如下图:
参考:
React Native for Android 原理分析与实践:实现原理