React Native是Facebook发布的一个用JavaScript开发移动应用的开源框架。框架目前只支持iOS平台,但一经推出,便受到国内外移动开发者的追捧,从GitHub上的统计数据看,自React Native开源至今的3个月时间,已经有170位贡献者对项目进行了1790余次的提交。
在React Native之前,基于JavaScript开发跨平台移动应用的框架已经有很多,这些框架都采用构建WEB页面的方式,但由于DOM性能和浏览器单线程处理等问题,构建的应用在移动端体验差,虽然开发成本很低,仍然无法取代原生开发。React Native与其他框架不同,它使用JavaScript来调用原生控件,使应用运行在本地环境中,从而使应用在移动端的体验堪比原生应用。
React Native由于使用JavaScript调用原生控件,运行过程中需要JavaScript和原生语言进行频繁、高效的通讯。这一过程极其复杂,下面以iOS为例详述其过程。
React Native内部通讯机制图解
React Native使用了iOS自带的JavaScriptCore作为JS解析的引擎,但并未使用其提供的OC-JS(OC,即Object-C;JS,即JavaScript)通讯机制,而是自己实现了一套机制。在通讯机制中有一个称为模块配置表的配置文件,这个文件中记录了OC中可供JS调用的模块和方法。在OC和JS中分别有一个通讯桥,每个通讯桥中存储着一份模块配置表,这是OC-JS通讯的基础。详细的调用过程是这样的:
1、事件触发JS函数调用,事件包含定时事件、加载事件等。
2、JS通讯桥对调用进行分析,把调用的模块、方法解析成模块ID、方法ID
3、JS通讯桥根据返回函数生成返回函数ID,再联合调用参数、模块ID、方法ID生成一个消息模型,然后将模型置于消息队列中,等待OC来读取。
4、OC通讯桥调用JS的某个方法时,JS在返回数据中插入消息队列的数据,OC在消息队列中将消息模型取出。
5、OC根据模块配置表解析消息模型,找到OC中对应的模块和方法。
6. RCTModuleMethod对象对传递的JS参数进行转换和组装处理,然后通过NSInvocation动态调用OC方法,同时RCTModuleMethod生成block回调对象。
7、OC方法调用技术后,获取调用的返回值和返回函数ID,执行block回调。
8、block执行JS消息队列固有的函数回调方法,并将返回函数ID和返回值传递给该方法。
9、JS消息队列根据返回函数ID,找到对应的JS函数。
10、调用该JS函数,传递返回值,完成回调。
在第4步中并未采用JS直接调用OC的方式,而是使用了消息队列来存储JS对OC的调用并等待OC读取,这表明在React Native中,OC与JS通讯是单向的。这一过程是建立在严格的事件响应机制基础上的:只有在事件触发的时候,JS代码才会执行,由于采用了原生控件,事件触发的时候,OC程序必然也会运行,OC去调用JS,便可将JS消息队列中的消息全部读取并处理。在这个过程中,JS充当了数据源的角色,OC是控制器,调用JS数据源并进行解析,然后映射到对应OC模块上。
以上过程便是JavaScript和Object-C通讯的全部过程细节,整个过程的关键点在于:模块化、ID传递、封装调用、事件响应。这一个过程确实很复杂,但得益于JavaScriptCore和Object-C的高性能,相比于WEB页面的DOM操作,这一过程运行极为高效,体验几乎媲美原生应用。