React Native架构分析

  • 时间:
  • 浏览:0
  • 来源:新大发快三—大发彩票APP

public native void callFunction(int moduleId, int methodId, NativeArray arguments);

write once, 完整篇 跨平台。

对于Android 开发者, 普通安卓多线程池池 入口是Activity.onCreate()法律依据 , 主要有另一个对象

到此,转入Java层. 从native module配置表中,取到对应module和method,并执行。

至此, JS端调用完毕, queue中数据要等待的图片 Native层通过bridge来取。

Class[] parameterTypes = {ReactApplicationContext.class};                    java.lang.reflect.Constructorconstructor=c.getConstructor(parameterTypes);Object[] parameters ={reactContext};                    NativeModulemodule= (NativeModule)constructor.newInstance(parameters);modules.add(module);                }catch (Exception e){

对于JS开发者来说, 整个RN APP就还都可否 了另一个JS文件, 而开发者前要编写的就还都可否 了如上次要。主太多太多太多太多 另一个次要:

对于 Android 开发者来说, RN是另一个普通的安卓多线程池池 添加一堆事件响应, 事件来源主太多太多太多太多 JS的命令。主要有另一个线程池池 ,UI main thread, JS thread。 UI thread创建另一个APP的事件循环后,就挂在looper等待的图片 事件 , 事件驱动个人的对象执行命令。 JS thread 运行的脚本合适底层数据分派器, 不断上传数据,转化成UI 事件, 通过bridge转发到UI thread, 从而改变真实的View。 后边再深一层发现, UI main thread 跟 JS thread更像是CS 模型,JS thread更像服务端, UI main thread是客户端, UI main thread 不断询问JS thread让你请求数据,太多太多太多太多 数据有变,则更新UI界面。

@OverridepublicList createNativeModules(ReactApplicationContext reactContext){

在线资源

*太多太多太多太多 bridge,  JS和 JAVA是异步互通,太多太多太多太多 实现复杂化多API的逻辑,让让你意味着次要速率损耗在多线程池池 通信。JS 异步的编程法律依据多几次少带来有些不便。*太多太多太多太多 bridge,  太多太多太多太多 有些场景做还都可否 了及时响应。比如帧动画的实时控制。*Android版本刚推出不完善,让你目前RN版本还在不停的更新中, 太多太多太多太多 处在暗坑。*加入JS引擎, 内存的控制比较麻烦,会比普通native增加不少。

RN框架最主要的太多太多太多太多 实现了一套JAVA和 JS通信的方案,该方案还前要做到比较简便的互调对方的接口。一般的JS运行环境是直接扩展JS接口,让你JS通过扩展接口发送信息到主线程池池 。但RN的通信的实现机制是单向调用,Native线程池池 定期向JS线程池池 拉取数据, 让你转成JS的调用预期,最后转交给Native对应的调用模块。太多太多太多太多 最终同样也还前要达到Java和 JS 定义的Module互相调用的目的。

分析代码可知,消息线程池池 创建于ReactContext环境初始化时, MessageQueueThread.java当中, 该消息队列主要接收系统事件(如 Vsync、timer、doFrame、backkey)、UI事件(如键盘弹起、滚动等)以及 callback事件(JS 的回调函数)。

2、 组件扩展(UI component)

new ToastModule(reactContext)));

m_callback 函数是在bridge初始化的太多太多太多太多 设置到c++层, 如:

1、JS调用java

动态注入的API插件实现方案,能跟h5容器共用实现。

代码离线

ReactInstanceManager, 构建React世界的运行环境,发送事件到JS世界, 驱动整个React世界运转。 通过builder还前要创建不同的React环境, 比如内置js 路径, 开发环境dev的js名字,否有有支持调试等。doInBackground会加载指定的JS文件, onPostExecute会调用runApplication接口运行JS APP。

https://facebook.github.io/react-native/docs/native-modules-android.html#content

一般来说,JS 开发者只前要开发各个组件对象,监听组件事件, 让你利用framework接口调用render法律依据渲染组件。

bridge会把你这俩 个queue交给parseMethodCalls解析, 让你通过JNI回调函数转发到Java层

此刻进入JS 世界, 开发者的js 得话连同react js框架层被执行。该步骤最终得话是执行AppRegistry.registerComponent注册另一个APP组件,但还很难到开始英文渲染。

所有的APP在操作系统中, 最终后该使用另一个事件循环来运行。

ReactRootView, Android 标准的FrameLayout对象,另外另一个功能是提供react 世界的入口,函数startReactApplication实际调用attachMeasuredRootView触发react世界的初始化。

通过JS 的require和 apply函数拼接一段JS 代码, 让你用javascriptCore的脚本运行接口执行,并得到返回值。

RN 会把应用的JS代码(包括依赖的framework)编译成另一个js文件(一般命名为index.android.bundle), , RN的整体框架目标太多太多太多太多 为了解释运行你这俩 js 脚本文件,太多太多太多太多 是js 扩展的API, 则直接通过bridge调用native法律依据; 太多太多太多太多 是UI界面, 则映射到virtual DOM你这俩 虚拟的JS数据形态学 中,通过bridge 传递到native , 让你根据数据属性设置各个对应的真实native的View。 bridge是并否有JS 和 JAVA代码通信的机制, 用bridge函数传入对方module 和 method即可得到异步回调的结果。

ReactRootView第一次onMeasured计算完成, 让让你利用ReactInstanceManager创建 ReactContext上下文环境。重要的是初始化bridge以及加载js文件, 利用JSBundleLoader法律依据加载index.android.bundle. 如图

new AsyncStorageModule(reactContext),

一般说的是图片资源比较多, RN 使用控件显示图片,如:

e.printStackTrace();

1、 模块扩展(native module)

require 所有依赖到的组件, 合适java中的import 太多太多太多太多 c++ 中的include。

https://facebook.github.io/react-native/docs/native-components-android.html#content

var styles = StyleSheet.create({, 创建CSS 样式,实际上会直接当做参数直接反馈到后边的React.createElement

MyReactPackage, 配置当前APP 前要加载的模块,RN 的JS框架会在初始化阶段就会把native的模块按照配置加载到JS数据形态学 中(MessageQueue), 从而不能在JS 层即可直接判断native否有有支持某个模块。支持并否有类型模块配置, native module(实际太多太多太多太多 不前要操作View形态学 的API), view managers(实际是映射到virtual DOM中的View组件), JS module 。

JS调用java 使用通过扩展模块require('NativeModules')获取native模块,让你直接调用native公开的法律依据,比如require('NativeModules').UIManager.manageChildren()。 JS 调用require('NativeModules')实际上是获取MessageQueue后边的另一个native模块列表的属性, 如:

太多太多太多太多 就在JS引擎中运行了一段JS代码并得到返回值,实现了JAVA层到JS层的调用。每次有JAVA对JS的访问, 则在返回值中从JS层的messageQueue.js中抓取太多太多太多太多 次要的一堆JS calls。太多太多太多太多 JAVA层要把时间同步、 系统帧绘制等事件传递给JS, 让你queue中的JS calls后该在很短的时间内被抓取。

List modules = new ArrayList();

三、 通信机制

native层会在一定条件下触发事件, 通过bridge调用callFunctionReturnFlushedQueue

RN 这套框架让 JS开发者还前要大次要使用JS代码就还前要构建另一个跨平台APP。 Facebook官方说法是learn once, run everywhere, 即在Android 、 IOS、 Browser各个平台,多线程池池 画UI和写逻辑的法律依据都大致相同。太多太多太多太多 JS 还前要动态加载,从而理论上还前要做到write once, run everywhere, 当然要做额外的适配除理。如图:

new FrescoModule(reactContext),

让你在回调函数中,陆续调用ReactCallback对象的call法律依据,weakCallback太多太多太多太多 java层初始化bridge时传入的NativeModulesReactCallback对象,也太多太多太多太多 ReactCallback的子类。

for (int i = 0; i < mModuleList.size(); i++) {

H5容器和RN容器融合方案

try {

1、JS入口

接着就等待的图片 Native事件驱动渲染JS端定义的APP组件。

一、 整体架构

if (mModuleList != null && mModuleList.size() > 0) {

在线更新

2、Native 入口

java层还前要调用的JS模块主要在CoreModulesPackage.createJSModules法律依据配置,有:

2、java调用JS

六、 总结

太多太多太多太多 ReactInstanceManager 中运行JS APP组件,JAVA 是调用catalystInstance.getJSModule 法律依据获取JS 对象,让你直接访问对象法律依据runApplication。实际上getJSModule 返回的是js对象在java层的映射对象。

AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject); 以上另一个更像是参数,你这俩 才是JS 多线程池池 的入口。即把当前APP的对象注册到AppRegistry组件中, AppRegistry组件是js module。

官方文档操作:

让你不管是离线包内资源还是系统资源,倘若能转添加Android 统一资源定位URI对象,即可获取到图片。

和 invokeCallbackAndReturnFlushedQueue ,得到的返回值太多太多太多太多 你这俩 个queue。

当运行环境准备完毕, 则调用bridge法律依据运行上步注册的APP组件,触发一连串JS 和 Native相互通信,配合事件驱动, 从而完成native世界的渲染。如图利用bridge法律依据运行后边注册的JS APP组件的runApplication法律依据:

二、 代码流程

四、 扩展机制

离线包支持。 目前RN官方支持内置APK打包以及dev server在线更新。而实际上,一般的容器后该实现一套离线包发布平台。大致的实现方案是自定义另一个JSBundleLoader,对接到应用管理发布平台。

RN前要另一个JS的运行环境, 在IOS上直接使用内置的javascriptcore, 在Android 则使用webkit.org官方开源的jsc.so。 此外还集成了有些开源组件,如fresco图片组件,okhttp网络组件等。

分离react 框架代码和应用业务代码。目前官方的生产工具是把框架代码和业务代码弄成另一个bundle。 但框架代码很大,前要共用, 让你要分离出框架代码单独前置加载。 应用业务代码变成很小一段JS代码单独发布。太多太多太多太多 每次都加载框架代码, 启动业务代码会很难,另一个helloworld都前要4秒左右。初步实践方案是把ReactInstanceManager设置成全局变量共享,在Native APP 启动初始化太多太多太多太多 第一次进入RN APP时初始化ReactInstanceManager。你这俩 让让你意味着多个RN APP全局变量冲突。

Log.i("MyReactPackage", "add Module:" + mModuleList.get(i));

五、 离线加载

new NetworkingModule(reactContext),

var AwesomeProject = React.createClass 创建APP, 让你在render函数中返回UI界面形态学 (采用JSX ), 实际经过编译, 后该变成JS 代码, 比如 变成 React.createElement(View,{style:{flex:1}},

Log.i("MyReactPackage", "add Module Exeception:" + e);

调用RemoteModules 的法律依据, 实际是把moduleID、methodId、args倒进另一个queue保存。

Class c = Class.forName(mModuleList.get(i));

3、事件循环

离线包更新主要依赖应用管理发布平台,大致还前要做到跟H5离线包一致。

而实际上,JS 也是单线程池池 事件循环,不管是 API调用, virtural DOM同步, 还是系统事件监听, 都是异步事件,采用Observer(观察者)模式监听JAVA层事件, JAVA层会把JS 关心的事件通过bridge直接使用javascriptCore的接口执行固定的脚本, 比如"requrire (test_module).test_methode(test_args)"。此时,UI main thread合适work thread, 把系统事件太多太多太多太多 用户事件往JS层抛,一同,JS 层太多太多太多太多 断调用模块API太多太多太多太多 UI组件 , 驱动JAVA层完成实际的View渲染。JS开发者只前要监听JS层framework定义的事件即可。如图即JS thread 的消息队列循环:

太多太多太多太多 调用JSModules对象的法律依据,则会动态代理跳转到(mBridge).callFunction(moduleId, methodId, arguments);

2、 待研究

使用_genModules 加载所有native module到 RemoteModules数组。RemoteModules次要都是另一个映射到native module的JS对象。

JS 层支持 Fragment manager

跟普通APP不同是,此时JS thread合适work thread, JS会把对应的事件太多太多太多太多 数据通过bridge发送到UI thread。 如图即是native Java层收到的JS事件的除理函数:

通过source属性设置图片资源路径, 映射到native层:

动画的实现法律依据。

太多太多太多太多 RN太多太多太多太多 具备太多太多太多太多有的灵活, JS也还前要做到太多太多太多太多有大型控件,太多太多太多太多有native UI扩展前要定义JS 和 native边界, 什么是JS 实现, 什么是native实现。

接着调用ReactBridge中声明的JNI 函数,

Facebook 于2015年9月15日推出react native for Android 版本, 添加2014年底太多太多太多太多 开源的IOS版本,至此RN (react-native)真正成为跨平台的客户端框架。本篇主太多太多太多太多 从分析代码入手,探讨一下RN在安卓平台上是怎么构建一套JS的运行框架。

太多太多太多太多 是静态资源,则直接URI统一定位。太多太多太多太多 是动态资源, 比如要通过网关获取到base64格式的图片,则前要native扩展有点接口。

1、 太多太多太多太多 瓶颈

官方文档操作:

modules.addAll(Arrays.asList(

}}        }        return modules;    }

资源离线

对于JS开发者来说, 画UI只前要画到virtual DOM 中,不前要有点关心具体的平台, 还是太多太多太多太多 的单线程池池 开发,还是太多太多太多太多 HTML 组装UI(JSX),还是太多太多太多太多 的样式模型(次要兼容 )。RN的界面除理除了实现View 增完整篇 查的接口之外,还自定义一套样式表达CSSLayout,这套CSSLayout也是跨平台实现。 RN 拥有画UI的跨平台能力,主太多太多太多太多 加入Virtual DOM编程模型,该法律依据一方面还前要照顾到JS开发者在html DOM的次要传承, 让JS 开发者还前要用类似于DOM编程模型就还前要开发原生APP , 个人面则还前要让Virtual DOM适配实现到各个平台,实现跨平台的能力,让你为未来增加更多的想象空间, 比如react-cavas, react-openGL。而实际上react-native也是从react-js演变而来。

如图即ReactRootView往JS 传递键盘弹出的事件:

而对于Android 开发者, Android 太多太多太多太多 为APP创建另一个默认的 Main Looper, 不管是Android System 还是JS 事件都是发送到Main thread通过UI渲染出来。如图即是MessageQueueThread.java直接使用主线程池池 Looper。

new WebSocketModule(reactContext),

太多太多太多太多 react模块加载主要在ReactPackage类配置,让你扩展还前要通过反射、外部依赖注入等机制,还前要做到跟H5容器一样实现动态插拔的插件式扩展。比如API扩展, 通过外部传入扩展模块的类名即可反射构造函数创建新的API: