React Native For Android 架构初探
版权声明:本文由王少鸣原创文章,转载请注明出处:
文章原文链接:https://www.qcloud.com/community/article/171
来源:腾云阁 https://www.qcloud.com/community
Facebook 在2015.9.15发布了 React Native for Android,把JavaScript 开发技术扩展到了Android平台。React Native 让开发者使用 JavaScript 和 React 编写应用,利用相同的核心代码就可以创建 基于Web,iOS 和 Android 平台的原生应用。本文将浅析Android React的架构及相关基础知识。
环境搭建及调试相关知识参考官网文档即可,本文不再赘述。
一.React架构分析
1.层次架构:

Java层:java层为逻辑入口,启动C++层的javascript解析器,执行js通过c++传递来的渲染指令,从而构建NativeUI等。java层依赖于众多优秀开源库,在图片处理使用的是Fresco,网络通信使用的是okhttp,当然还有众多工具类,如Json解析工具jackson,Animation知名开源库NineOldAndroids,小而全的底层工具类bolts等,在java层均封装为Module。java层核心jar包是react-native.jar,封装了众多上层的interface,如Module,Registry,bridge等,下面会以App的启用过程,完整分析java层的架构。
C++层:c++层最主要是封装了JavaScriptCore,执行对js的解析。基于JavaScriptCore,Web开发者可以尽情使用ES6的新特性,如class、箭头操作符等,而且 React Native运行在JavaScriptCore中的,完全不存在浏览器兼容的情况。Bridge桥接了java <> js 通信的核心接口。JSLoader主要是将来自assets目录的或本地file加载到javascriptCore,再通过JSCExectutor解析js文件。
Js层:主要处理事件分发及UI Layout,主要有以下几个部件:
- Component:Js层通js/jsx编写的Virtual Dom来构建Component或Module,Virtual DOM是DOM在内存中的一种轻量级表达方式,可以通过不同的渲染引擎生成不同平台下的UI。component的使用在 React 里极为重要, 因为component的存在让计算 DOM diff 更高效。
- Lifecycle&Data:React 组件通过内部的 state 变量控制生命周期及事件回调。如getInitialState方法用于定义组件初始状态,后续组件可通过 this.state 属性读取该状态。当事件触发(或者主动调用setState方法更新数据)导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,重新渲染组件。
- Layout:React使用css-layout,css-layout使用javascript实现了flexbox ,不依赖于DOM,能编译成Object-C或者Java,最终达到跨平台的展示目的,但暂时不支持css3,暂时只能支持简单的布局和普通的动画。
2.Js与Java通信机制:
在Java层与Js层的bridge分别存有相同一份模块配置表,Java与Js互相通信时,通过bridge里的配置表将所调用模块方法转为{moduleID,methodID,args}的形式传递给处理层,处理层通过bridge的模块配置表找到对应的方法执行,如果有callback,则回传给调用层。在了解ReactAndroid APP启动后,第三部分会详细讲这套机制。
二.从应用启动到页面加载完成分析

上图为 Android React 加载过程的解析,下面先概要描述上层核心类及原理,再梳理核心的启用步骤。
Core Class:
1.ReactInstanceManager:主要是用来创建及管理Catalyst的实例的上层接口,控制开发调试,生命周期与ReactRootView所在activity保持一致。
2.ReactRootView:为启动入口核心类,负责监听及分发事件并重新渲染元素,App启动后,其将作为App的root view。
3.CatalystInstance:顶级异步JSCAPI封装类,提供Java与Js互通的环境,通过ReactBridge将Svr的Js Bundle传送到Js引擎。
4.NativeModuleRegistry:Java层模块注册表,即暴露给Js的API集合。
5.JavascriptModuleRegistry:Js层模块注册表,负责将所有JavaScriptModule注册到CatalystInstance,通过Java动态代理调用到Js。
6.CoreModulePackage:定义核心框架模块,创建NativeModules&JsModules。
启动过程的解析:
1.在ReactInstanceManager时会配置应用所需的java模块与js模块之后,通过ReactRootView的startReactApplication启动APP。
2.在创建ReactInstanceManager同时会创建用于加载JsBundle的JSBundlerLoader,并传递给CatalystInstance。
3.CatalystInstance会创建Java模块注册表及Javascript模块注册表,并遍历实例化模块。
4.CatalystInstance通过JSBundlerLoader向Node Svr请求Js Bundle,并传递给JSCJavaScriptExectutor,最后传递给javascriptCore,再通过ReactBridge通知ReactRootView完成渲染。
三.Js与Java通信机制
Java与Js之间的调用,是以两边存在两边存在同一份模块配置表,最终均是将调用转化为{moduleID, methodID,callbackID,args},处理端在模块配置表里查找注册的模块与方法并调用。
Java -> Js :Java通过注册表调用到CatalystInstance实例,透过ReactBridge的jni,调用到Onload.cpp中的callFunction,最后通过javascriptCore,调用BatchedBridge.js,根据参数{moduleID,methodID}require相应Js模块执行。详细流程如下图。
Js -> Java:JS不主动传递数据调用Java。在需要调用调Java模块方法时,会把参数{moduleID,methodID}等数据存在MessageQueue中,等待Java的事件触发,再把MessageQueue中的{moduleID,methodID}返回给Java,再根据模块注册表找到相应模块处理。详细流程如下图。

四.总结
React将UI分解成组件,废弃了模板,统一视图逻辑标签,使构建的视图更容易扩展和维护,Vitual Dom更是其提高性能的亮点,React 中的Dom并不保证马上影响真实的Dom,React会等到事件循环结束,利用diff算法,通过当前新Dom树与之前的Dom树作比较,计算出最小的步骤更新真实的DOM。
Android React的推出更使得利用相同的核心代码就可以创建 Web,iOS 和 Android 平台的原生应用,但目前Android React的HelloWorld基础库将近7m,落地项目仍需要精简,目前我们正在精简中。当然,对于Andriod版本也有考验,仅支持 Android 4.1 (API 16) 以上的版本(iOS 7.0),当然,在系统不支持情况下,H5可以作为后备方案。
我们后续会持续关注Android React的动态,向大家继续推送更多关于Android React的文章。(底部有关于Android React所有类库的描述)
React Native For Android 架构初探的更多相关文章
- React native 之android的图标和启动图片
哎哎呀呀,上篇说到了react native的IOS的图标和启动图片的设置,其实最主要的是尺寸!相应的尺寸设定好了以后就不会报错了! ok~这篇说的是React native的android的图标和启 ...
- 【React Native开发】React Native For Android环境配置以及第一个实例(1)
年9月15日也公布了ReactNative for Android,尽管Android版本号的项目公布比較迟,可是也没有阻挡了广大开发人员的热情.能够这样讲在2015年移动平台市场上有两个方向技术研究 ...
- React Native for Android 学习
前言 Facebook 在2015.9.15发布了 React Native for Android,把 JavaScript 开发技术扩展到了移动Android平台.基于React的React Na ...
- React Native for android 项目驱动教程
第一节 搭建开发环境 第二节 显示页面标题 第三节 实现页面布局 # React native是什么? React Native,是颠覆性的移动开发技术.它使用js开发,又是原生应用,不同于Hybri ...
- React Native之新架构中的Turbo Module实现原理分析
有段时间没更新博客了,之前计划由浅到深.从应用到原理,更新一些RN的相关博客.之前陆续的更新了6篇RN应用的相关博客(传送门),后边因时间问题没有继续更新.主要是平时空余时间都用来帮着带娃了,不过还是 ...
- React Native for Android应用名及图标修改
应用开发完了,总不能顶着MyProject和小机器人图标就发布了吧?在发布之前,有多处需要修改的地方.今天我们来全面的看一下 应用ID 俗称PackageName,或APP ID.注意,在gradle ...
- react native 之 Android物理返回键
基本用法 根据文档,安卓back键的处理主要就是一个事件监听: BackAndroid.addEventListener('hardwareBackPress', this.onBackPressed ...
- React Native for Android 热部署图片自己定义方案
情景 热部署时,我们期望升级包中包括js代码与图片资源. bundle的热部署网上已经有两种方案了,一种是用反射,一种是利用RN自带函数.将bundle初始化时直接放到指定文件夹下,之后通过替换bun ...
- 混合开发的大趋势之一React Native与Android联调
转载请注明出处:王亟亟的大牛之路 先安利,有空我都会更,看到的好东西都会放进来:https://github.com/ddwhan0123/Useful-Open-Source-Android 公司某 ...
随机推荐
- iosanimationWithKeyPath
animationWithKeyPath的值: transform.scale = 比例轉換 transform.scale.x = 闊的比例轉換 transform.scale.y ...
- mysql正则匹配解决查询一个字段是否在另一个字段中
select b.filter_name , count(*) from at_goods a , at_search_filter bwhere a.application REGEXP b.fil ...
- CodeForces 483B Friends and Presents
Friends and Presents Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I ...
- 【转载】Ogre的内存分配策略
原文:Ogre的内存分配策略 读这个之前,强烈建议看一下Alexandrescu的modern c++的第一章关于policy技术的解释.应该是这哥们发明的,这里只是使用. 首先列出涉及到的头文件:( ...
- genome MuSic安装
系统:ubuntu 15.04全程在root权限下安装 首先安装软件samtools ,必须是samtools-0.1.19 版本tar jxf samtools-0.1.19.tar.bz2cd s ...
- factory工厂模式之抽象工厂AbstractFactory
* 抽象工厂: 意图在于创建一系列互相关联或互相依赖的对象. * 每个工厂都会创建一个或多个一系列的产品 * 适用于:产品不会变动,开始时所有产品都创建好,然后根据分类获取想要的 某一类产品(很像sp ...
- HNOI2006-公路修建问题(二分答案+并查集)
公路修建问题 OI island是一个非常漂亮的岛屿,自开发以来,到这儿来旅游的人很多.然而,由于该岛屿刚刚开发不久,所以那里的交通情况还是很糟糕.所以,OIER Association组织成立了,旨 ...
- 不要温柔地走入AMD
1.无依赖情况 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...
- 关于linux 卸载问题
网上找了一套引擎 非用protocbuff 2.4.1 结果机器上已经装好了2.6.1 网上找了好多办法都行不通 最后终于在一个群里问到 mark一下 例如 我想卸载当前得protoc 那么 第一步 ...
- 应用部署到JBOSS上遇到的问题
原来应用在WAS7.0下,移植到JBOSS eap5.1.2下后,遇到了一些问题,特此记录: 1.数据源配置 在was中,datasource中获取数据源名称时,直接写was中配置的数据源名称即可.而 ...