PS:該文章僅供個人學習交流之用,不當之處,還請指出,歡迎拍磚吐槽!
一.React Native 框架分析
層次架構:
Java層:該層主要提供了Android的UI渲染器UIManager(將JavaScript映射成Android Widget)以及一些其他的功能組件(例如:Fresco、Okhttp)等,在java層均封裝為Module,java層核心jar包是react-native.jar,封裝了眾多上層的interface,如Module,Registry,bridge等。
C++層:主要處理Java與JavaScript的通信以及執行JavaScript代碼工作,該層封裝了JavaScriptCore,執行對js的解析。基于JavaScriptCore,Web開發者可以盡情使用ES6的新特性,如class、箭頭操作符等,而且 React Native運行在JavaScriptCore中的,完全不存在瀏覽器兼容的情況。Bridge橋接了java , js 通信的核心接口。JSLoader主要是將來自assets目錄的或本地file加載javascriptCore,再通過JSCExectutor解析js文件。
Js層:該層提供了各種供開發者使用的組件以及一些工具庫。
Component:Js層通js/jsx編寫的Virtual Dom來構建Component或Module,Virtual DOM是DOM在內存中的一種輕量級表達方式,可以通過不同的渲染引擎生成不同平臺下的UI。component的使用在 React 里極為重要, 因為component的存在讓計算 DOM diff 更高效。
ReactReconciler : 用于管理頂層組件或子組件的掛載、卸載、重繪。
注:JSCore,即JavaScriptCore,JS解析的核心部分,IOS使用的是內置的JavaScriptCore,Androis上使用的是 https://webkit.org 家的jsc.so。
Java層核心類及原理,如下所示:
ReactContext
ReactContext繼承于ContextWrapper,是ReactNative應用的上下文,通過getContext()去獲得,通過它可以訪問ReactNative核心類的實現。
ReactInstanceManager
ReactInstanceManager是ReactNative應用總的管理類,創建ReactContext、CatalystInstance等類,解析ReactPackage生成映射表,并且配合ReactRootView管理View的創建與生命周期等功能。
ReactRootView
為啟動入口核心類,負責監聽及分發事件并重新渲染元素,App啟動后,其將作為App的root view。
CatalystInstance
CatalystInstance是ReactNative應用Java層、C++層、JS層通信總管理類,總管Java層、JS層核心Module映射表與回調,三端通信的入口與橋梁。
JavaScriptModule
JavaScriptModule是JS Module,負責JS到Java的映射調用格式聲明,由CatalystInstance統一管理。
NativeModule
NativeModule是ava Module,負責Java到Js的映射調用格式聲明,由CatalystInstance統一管理。
JavascriptModuleRegistry
JS Module映射表,負責將所有JavaScriptModule注冊到CatalystInstance,通過Java動態代理調用到Js。
NativeModuleRegistry
是Java Module映射表,即暴露給Js的API集合。
CoreModulePackage
定義核心框架模塊,創建NativeModules&JsModules。
啟動過程的解析:
1.ReactInstanceManager創建時會配置應用所需的java模塊與js模塊,通過ReactRootView的startReactApplication啟動APP。
2.在創建ReactInstanceManager同時會創建用于加載JsBundle的JSBundlerLoader,并傳遞給CatalystInstance。
3.CatalystInstance會創建Java模塊注冊表及Javascript模塊注冊表,并遍歷實例化模塊。
4.CatalystInstance通過JSBundlerLoader向Node Server請求Js
Bundle,并傳遞給JSCJavaScriptExectutor,最后傳遞給javascriptCore,再通過ReactBridge通知ReactRootView完成渲染。
Js與Java通信機制
Java與Js之間的調用,是以兩邊存在兩邊存在同一份模塊配置表,最終均是將調用轉化為{moduleID,
methodID,callbackID,args},處理端在模塊配置表里查找注冊的模塊與方法并調用。
1. Java 調用Js
Java通過注冊表調用到CatalystInstance實例,透過ReactBridge的jni,調用到Onload.cpp中的callFunction,最后通過javascriptCore,調用BatchedBridge.js,根據參數{moduleID,methodID}require相應Js模塊執行。流程如下圖:
1. Js 調用Java
如果消息隊列中有等待Java 處理的邏輯,而且 Java 超過 5ms 都沒有來取走,那么 JavaScript 就會主動調用 Java 的方法,在需要調用調Java模塊方法時,會把參數{moduleID,methodID}等數據存在MessageQueue中,等待Java的事件觸發,把MessageQueue中的{moduleID,methodID}返回給Java,再根據模塊注冊表找到相應模塊處理。流程如下圖:
參考:
React Native for Android 原理分析與實踐:實現原理