React Native For Android 架构初探

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

时间: 2024-10-13 14:55:17

React Native For Android 架构初探的相关文章

【React Native开发】React Native For Android环境配置以及第一个实例

转载请标明出处: http://blog.csdn.net/developer_jiangqq/article/details/50456967 本文出自:[江清清的博客] (一)前言 FaceBook早期开源发布了React Native For IOS,终于在2015年9月15日也发布了ReactNative for Android,虽然Android版本的项目发布比较迟,但是也没有阻挡了广大开发者的热情.可以这样讲在2015年移动平台市场上有两个方向技术研究比较火,第一种为阿里,百度,腾讯

React Native嵌入Android原生应用中

开发环境准备 首先你要搭建好React Native for Android开发环境, 没有搭建好的可以参考:React Native for Android Windows环境搭建 用Android Studio新建Android原生项目 我创建了一个名叫ReactNativeDemo的原生项目. 把React Native集成到原生项目当中 利用Windows命令行在项目根目录(ReactNativeDemo文件夹)下执行下面三行命令: npm init npm install –save

工作方向转变—— React Native For Android

既然选择了北漂,如果不玩命,就被命运玩. 最近,Fackbook将自己的著名的框架React Native,宣称支持了Android了.根据公司和朋友的推荐,个人机会在2015年的剩下时间用来研究使用此框架,来完成自己的业务.希望了解熟此框架的大神给予我多多指点. 为什么要使用此框架? 下面引入自新闻报道 开源已是大势所趋,连习惯专有化的巨头也发现了它的力量.Facebook 是其中最积极之一,近几年陆续开源的项目已有 30 多个.刚刚社交巨头又在一年一度的 @Scale 大会上宣布开源原生应用

3.React Native在Android中自定义Component和Module

React Native最终展示的UI全是Native的UI,将Native的信息封装成React方便的调用.那么Native是如何封装成React调用的?Native和React是如何交互的? ViewManager UI组件:将Native的UI暴露出来供JS调用. Native组件封装成JS组件供JS调用.这里的一个问题是怎么将Native中的属性用在JS中,以及属性可以有哪些类型的?可以先思考一下. 下面Native的代码自定义了一个View并定义了一个变化的属性color. publi

react native 之 Android物理返回键

基本用法 根据文档,安卓back键的处理主要就是一个事件监听: 1 BackAndroid.addEventListener('hardwareBackPress', this.onBackPressed); 2 BackAndroid.removeEventListener('hardwareBackPress', this.onBackPressed); 在starter-kit里,我们在App这一级别,实现了按back键回退导航栈的功能: 1 class App extends React

Android React Native在Android Studio中执行bundleReleaseJsAndAssets 打包失败的解决方法

这个坑在文章记一次在Windows上搭建React Native Android环境踩过的坑中我已经提到过,当时找不到解决方法,只能开一个命令提示符终端独立执行打包.就像这样子 react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output C:\Users\Administrator\Desktop\AwesomeProject\android\app\build\

React Native for Android 热部署图片自己定义方案

情景 热部署时,我们期望升级包中包括js代码与图片资源. bundle的热部署网上已经有两种方案了,一种是用反射,一种是利用RN自带函数.将bundle初始化时直接放到指定文件夹下,之后通过替换bundle文件实现代码热部署. 我们希望图片也能够实现热部署,以下是一个比較简单的解决方式. 详细需求:client解析从server下发的压缩包(zip),当中含js源文件index.android.bundle 和 图片包,解压后ReactNative指向 解压后index.android.bund

React Native IOS源码初探

原文链接 http://www.open-open.com/lib/view/open1465637638193.html 每个项目都有一个入口,然后进行初始化操作,React Native 也不例外.一个不含 Objective-C 代码的项目留给我们的唯一线索就是位于 AppDelegate 文件中的代码: RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"re

React Native在Android平台运行gif的解决方法

概述 目前RN在Android平台上不支持gif格式的图片,而在ios平台是支持的,期待以后的版本中系统也是可以默认支持Android的.首先说下在ios平台怎么加载gif呢? <Image source= {require('./img/loading.gif')} style = {styles.loading}/> 完整实例: xport default class Loading extends React.Component { render(){ if (!this.props.i