PS:該文章僅供個(gè)人學(xué)習(xí)交流之用,不當(dāng)之處竿刁,還請(qǐng)指出猜扮,歡迎拍磚吐槽煮盼!
一.React Native 框架分析
層次架構(gòu):
Java層:該層主要提供了Android的UI渲染器UIManager(將JavaScript映射成Android Widget)以及一些其他的功能組件(例如:Fresco悠就、Okhttp)等梗脾,在java層均封裝為Module,java層核心jar包是react-native.jar盹靴,封裝了眾多上層的interface炸茧,如Module,Registry稿静,bridge等梭冠。
C++層:主要處理Java與JavaScript的通信以及執(zhí)行JavaScript代碼工作,該層封裝了JavaScriptCore改备,執(zhí)行對(duì)js的解析控漠。基于JavaScriptCore绍妨,Web開(kāi)發(fā)者可以盡情使用ES6的新特性,如class柬脸、箭頭操作符等他去,而且 React Native運(yùn)行在JavaScriptCore中的,完全不存在瀏覽器兼容的情況倒堕。Bridge橋接了java 灾测, js 通信的核心接口。JSLoader主要是將來(lái)自assets目錄的或本地file加載javascriptCore垦巴,再通過(guò)JSCExectutor解析js文件媳搪。
Js層:該層提供了各種供開(kāi)發(fā)者使用的組件以及一些工具庫(kù)。
Component:Js層通js/jsx編寫(xiě)的Virtual Dom來(lái)構(gòu)建Component或Module骤宣,Virtual DOM是DOM在內(nèi)存中的一種輕量級(jí)表達(dá)方式秦爆,可以通過(guò)不同的渲染引擎生成不同平臺(tái)下的UI。component的使用在 React 里極為重要, 因?yàn)閏omponent的存在讓計(jì)算 DOM diff 更高效憔披。
ReactReconciler : 用于管理頂層組件或子組件的掛載等限、卸載爸吮、重繪。
注:JSCore望门,即JavaScriptCore形娇,JS解析的核心部分,IOS使用的是內(nèi)置的JavaScriptCore筹误,Androis上使用的是 https://webkit.org 家的jsc.so桐早。
Java層核心類(lèi)及原理,如下所示:
ReactContext
ReactContext繼承于ContextWrapper厨剪,是ReactNative應(yīng)用的上下文哄酝,通過(guò)getContext()去獲得,通過(guò)它可以訪問(wèn)ReactNative核心類(lèi)的實(shí)現(xiàn)丽惶。
ReactInstanceManager
ReactInstanceManager是ReactNative應(yīng)用總的管理類(lèi)炫七,創(chuàng)建ReactContext、CatalystInstance等類(lèi)钾唬,解析ReactPackage生成映射表万哪,并且配合ReactRootView管理View的創(chuàng)建與生命周期等功能。
ReactRootView
為啟動(dòng)入口核心類(lèi)抡秆,負(fù)責(zé)監(jiān)聽(tīng)及分發(fā)事件并重新渲染元素奕巍,App啟動(dòng)后,其將作為App的root view儒士。
CatalystInstance
CatalystInstance是ReactNative應(yīng)用Java層的止、C++層、JS層通信總管理類(lèi)着撩,總管Java層诅福、JS層核心Module映射表與回調(diào),三端通信的入口與橋梁拖叙。
JavaScriptModule
JavaScriptModule是JS Module氓润,負(fù)責(zé)JS到Java的映射調(diào)用格式聲明,由CatalystInstance統(tǒng)一管理薯鳍。
NativeModule
NativeModule是ava Module咖气,負(fù)責(zé)Java到Js的映射調(diào)用格式聲明,由CatalystInstance統(tǒng)一管理挖滤。
JavascriptModuleRegistry
JS Module映射表,負(fù)責(zé)將所有JavaScriptModule注冊(cè)到CatalystInstance崩溪,通過(guò)Java動(dòng)態(tài)代理調(diào)用到Js。
NativeModuleRegistry
是Java Module映射表,即暴露給Js的API集合斩松。
CoreModulePackage
定義核心框架模塊伶唯,創(chuàng)建NativeModules&JsModules。
啟動(dòng)過(guò)程的解析:
1.ReactInstanceManager創(chuàng)建時(shí)會(huì)配置應(yīng)用所需的java模塊與js模塊惧盹,通過(guò)ReactRootView的startReactApplication啟動(dòng)APP抵怎。
2.在創(chuàng)建ReactInstanceManager同時(shí)會(huì)創(chuàng)建用于加載JsBundle的JSBundlerLoader奋救,并傳遞給CatalystInstance。
3.CatalystInstance會(huì)創(chuàng)建Java模塊注冊(cè)表及Javascript模塊注冊(cè)表反惕,并遍歷實(shí)例化模塊尝艘。
4.CatalystInstance通過(guò)JSBundlerLoader向Node Server請(qǐng)求Js
Bundle,并傳遞給JSCJavaScriptExectutor姿染,最后傳遞給javascriptCore背亥,再通過(guò)ReactBridge通知ReactRootView完成渲染。
Js與Java通信機(jī)制
Java與Js之間的調(diào)用悬赏,是以?xún)蛇叴嬖趦蛇叴嬖谕环菽K配置表狡汉,最終均是將調(diào)用轉(zhuǎn)化為{moduleID,
methodID,callbackID闽颇,args}盾戴,處理端在模塊配置表里查找注冊(cè)的模塊與方法并調(diào)用。
1. Java 調(diào)用Js
Java通過(guò)注冊(cè)表調(diào)用到CatalystInstance實(shí)例兵多,透過(guò)ReactBridge的jni尖啡,調(diào)用到Onload.cpp中的callFunction,最后通過(guò)javascriptCore剩膘,調(diào)用BatchedBridge.js衅斩,根據(jù)參數(shù){moduleID,methodID}require相應(yīng)Js模塊執(zhí)行。流程如下圖:
1. Js 調(diào)用Java
如果消息隊(duì)列中有等待Java 處理的邏輯怠褐,而且 Java 超過(guò) 5ms 都沒(méi)有來(lái)取走畏梆,那么 JavaScript 就會(huì)主動(dòng)調(diào)用 Java 的方法,在需要調(diào)用調(diào)Java模塊方法時(shí),會(huì)把參數(shù){moduleID,methodID}等數(shù)據(jù)存在MessageQueue中奈懒,等待Java的事件觸發(fā)奠涌,把MessageQueue中的{moduleID,methodID}返回給Java,再根據(jù)模塊注冊(cè)表找到相應(yīng)模塊處理磷杏。流程如下圖:
參考:
React Native for Android 原理分析與實(shí)踐:實(shí)現(xiàn)原理
React Native For Android 架構(gòu)初探