在React Native中,JavaScript跟Object-C均有一个对应的中间件负责交互,源码中称为bridge,它们通过callback的形式进行传参,通过参数配置来触发OC的控件,从而达到以JavaScript来控制Native的目的。
React Native的设计理念:既拥有Native的用户体验、又保留React的开发效率。
React Native的口号: Learn Once,Write Anywhere.
前面说过,在React Native中,JS与OC共同遵循一个模块配置json,并以此为基础来相交传参及调用,而这个json中哪里来呢?我们从源头开始吧,下面代码中我们可以看到,OC将一个名为__fbBatchedBridgeConfig的变量插入到了js当中。而这个变量则是包含了两份配置的对象,这个对象中有两个属性,分别是remoteModules与localModules,remoteModules源于IOS中暴露出来的模块,提供给JS调用,而另一份localModules则为JS的模块配置,来源于React Native中JS暴露出来供OC调用的模块。
React/Base/RCTBridge.m
好了,数据源找到了,那么JS会在什么地方调用这份数据,又会用这份数据来做什么呢?下列这份代码中,我们可以看到,BatchedBridge.js直接从__fbBatchedBridgeConfig中拿到了模块配置表,并将其转传进BatchedBridgeFactory内:
Libraries/BatchedBridge/BatchingImplementation/BatchedBridge.js
BatchedBridgeFactory作为一个工厂类,在React Native流程中起了统一加工改造的作用,这边我们先看下MessageQueue函数,MessageQueue中文译为消息队列,是JSBridge中的一个消息队列类,用于管理等待传给OC的已格式化的模块及模块回调,这些模块在各自调用的时候是以(ModulesName,MethodName,Params)形式出来的,而经过MessageQueue格式化后这些参数名将被转存为(moduleID,methodID,params)的形式,前面是String形式,而后面则是Int形式,那么,MessageQueue究竟做了哪些事呢?上代码:
Libraries/Utilities/MessageQueue.js
在这里MessageQueue把ModuleName,MethodName,Params 这些字符串转化为整形的ID,参数及回调的suceess,fail函数被放进param中,并传递进_pushRequestToOutgoingItems里面运行,
_pushRequestToOutgoingItem同属MessageQueue,是其中的一个函数,主要操作一个开放给Native调用的数组:
_outgoingItems里面存放的都是等待native调用的moduleID,methodID,params,这些值分别在在3个数组存放,分别是moduleID:_REQUEST_MODULE_IDS,mothodID : REQUEST_METHOD_IDS,params:REQUEST_PARAMSS;
格式为:
_outgoingItems:[ [ moduleID1, moduleID2, ], [ methodID1, methodID2, ], [ params1, params2, ] ]
好了,JSBridge的前因后果如上所述,那么我们回头看下JSBridge主体是干什么的?
Libraries/BatchedBridge/BatchingImplementation/BatchedBridgeFactory .js
当Native中的事件触发触发ReactComponent的动作时,,ReactComponent将再次使用JSBridge中mapObject的回调function将结果放入MessageQueue中等待Native调用;
这里大致把JSBridge交互过程整理如下:
我们来看下ios模块配置表跟js本地模块配置表的内容:
JS暴露的模块:
IOS暴露的模块: