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所有类库的描述)

转载于:https://blog.51cto.com/12883930/1923182

React Native For Android 架构初探相关推荐

  1. Android方法调用实体类的值,React Native调用Android原生方法和传值

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 创建react native 项目:react-native init callAndroidProject cd ca ...

  2. React Native在Android当中实践(五)——常见问题

    React Native在Android当中实践(一)--背景介绍 React Native在Android当中实践(二)--搭建开发环境 React Native在Android当中实践(三)--集 ...

  3. React Native在Android当中实践(一)——背景介绍

    React Native在Android当中实践(一)--背景介绍 React Native在Android当中实践(二)--搭建开发环境 React Native在Android当中实践(三)--集 ...

  4. 20分钟理解React Native For Android原理

    原址:http://doslin.com/2017/03/15/react-native-source-code-analysis/ 前言 文中所有 RN 缩写指代React Native For A ...

  5. react native开发Android 篇——集成自定义的字体

    react native开发Android 篇--集成自定义的字体 第一种:link添加自定义字体 第二种:直接复制字体到`android/app/src/main/assets/fonts`目录下 ...

  6. React Native调用Android接口

    由于工作需要近期研究了下React Native调用Android接口,该文章将介绍自己在RN环境搭建和封装第三方SDK接口以及RN调用Android接口的趟坑过程.(第一次写博客,写的不好请大家勿喷 ...

  7. react native开发Android 篇——APP名称、图标、启动页

    react native开发Android 篇--APP名称.图标.启动页 设置APP名称 设置APP图标 设置启动页 隐藏启动页 设置APP名称 编辑 android/app/src/main/re ...

  8. React Native和Android整合详解

    前言 按照React Native的迭代速度,使用官网的文档,已经不能很顺利的实现React Native和Android的有效整合.React Native最新版本 已经是0.39.为了更好的讲解R ...

  9. React Native for Android 实践 — 实现知乎日报客户端

    React Native for Android 的发布,对一个 Android 开发者来说还是有相当的吸引力的.通过前面这篇博客:React Native for Android 入门老虎好不容易入 ...

  10. rn+与android+交互,React native 与Android原生交互方式(一)

    前言## 最近在做React Native开发的时候避免不了的需要原生模块和JS之间进行交互,其实RN和原生的通信大致分为两种情况:一种是Android主动向RN端发送事件和数据,另外一种是RN端被动 ...

最新文章

  1. 百度 71 个炸天的开源项目!你知道几个?
  2. python extractor_Python pyextractor包_程序模块 - PyPI - Python中文网
  3. SQL server 2005中无法新建作业(Job)的问题
  4. spring MVC之返回JSON数据(Spring3.0 MVC+Jackson+AJAX)
  5. element-ui表单验证:用户名、密码、电话、邮箱
  6. Java数组,Wat!
  7. 大数据可视化dataease(有所帮助)
  8. java数组基本用法(数组的声明/初始化及一些常用的数组操作)
  9. 计算机上硬盘驱动器,什么是计算机硬盘驱动器?它有什么作用?如何维护?
  10. linux软件安装文档总结
  11. # 数值计算:三角形积分
  12. Codeforces-1487 D. Pythagorean Triples(数学)
  13. 自媒体怎么同时多平台发文章?5分钟发到30+自媒体平台上
  14. 如何选择最好最适合你的MacBook
  15. HUD1873看病要排队
  16. PTA——基础编程题 | 7-27 冒泡法排序 (20分)
  17. Python学习心得——列表和元组的操作方法
  18. e5430支持服务器内存,手贱!入手了逆天护舒宝771四核E5430平台,再战IGAME GTX650TI BOOST...
  19. 2016年计算机考研408操作系统真题(客观题)
  20. 3G:3G通信的真实速度

热门文章

  1. 程序员修炼之道:从小工到专家
  2. 生命的书写,梦想的呈现
  3. 正则表达式:re.match、re.search、re.sub、re.compile、findall、re.finditer、re.split
  4. pandas小记:pandas高级功能
  5. Django项目实践2 - Django模板(网页多语种支持/国际化)
  6. python函数式编程:apply, map, lambda和偏函数
  7. 发送的消息无法订阅_微信服务号和订阅号的如何选择
  8. cmd管道无法接收特定程序返回值_CQRS amp; Event Sourcing — 解决检索应用程序状态问题的一剂良方...
  9. 力扣-1143 最长公共子序列/1035 不相交的线
  10. Harmony OS — Switch开关状态