[Cordova學習]4.Cordova(iOS)架構和實現

JS和Native的通信原理


圖中表示的是默認的JS和Native通信的方法(採用iframe)

  1. 保存Cordova_plugin.js的 插件文件名字和地址。
  2. 插件的API呼出時,通過調用Cordova的exec模塊將API的參數保存在CommandQueue的隊列中。  CALLBACK則保存在JS側的callbacks map裏面。
  3. 添加一個空的iframe,iframe的src則指向gap://ready
  4. 3的iframe的src設置以後,NATIVE側UIWebviewDelegate#shouldStartLoadWithRequest則被呼出來。
  5.  Webview的Delegatet判斷gap://ready的情況下,則執行commandDelegate的處理。
  6. commandDelegate則從JS側取出API的參數,內部實現則是通過 UIWebview#stringByEvaluatingJavaScriptFromString的返回值 取得CommandQueue裏面的參數轉換成JSON數據。
  7. 根據6的插件,執行NATIVE定義的插件實例。
  8. 插件中,有CALLBACK的情況下,成功失敗的結果通過UIWebview#stringByEvaluatingJavaScriptFromString執行JS,JS端則根據傳過來的CALLBACKID,從callbacks map取出回調函數並執行。


例:camera插件呼出的時序圖

JS到Natvie通信方式

從JS到Natvie的主要的通信方式有2種

  1. iframe的方法(默認)     

           該方法是添加iframe到html元素中,並設置iframe的src爲指定gap://ready,觸發NATIVE側UIWebview#shouldStartLoadWithRequest的方法。插件的參數則
           再從JS側的JSON數據取過來。插件的方法執行完了爲止都是同步處理。

        2.xmlHttpRequest的方法(iOS5.x版本因爲 -webkit-scroll的IFRAME有BUG,則推薦使用)

         JS側沒有明確定義這個XHR的方法則不可使用。插件具體的參數內容則設置在了頭部信息。
     execXhr.open('HEAD', "/!gap_exec?" + (+new Date()), true);     
     execXhr.setRequestHeader('cmds', iOSExec.nativeFetchMessages());     
    Native側NSURLRequest的協議,根據是否爲/!gap_exec來判定需要攔截。
    /!gap_exec的時候,則從頭部取得插件的具體參數。

      通信模式切換的方法下面鏈接有記載
      https://github.com/phonegap/phonegap/blob/master/lib/ios/guides/Changing%20the%20JavaScript%20to%20Native%20Bridge%20Mode.md    
      deviceready的事件處理中,執行XHR模式或者iframe模式的切換。    

var exec = cordova.require('cordova/exec'); 
exec.setJsToNativeBridgeMode(exec.jsToNativeModes.XHR_OPTIONAL_PAYLOAD);
var exec = cordova.require('cordova/exec'); 
exec.setJsToNativeBridgeMode(exec.jsToNativeModes.IFRAME_NAV);

插件導入流程

Natvie側

  1. APP啓動,MainViewController初始化之時,queue和command的DELEGATE初期化
  2. config.xml文件解析,插件名設置到數組,插件文件和插件名設置到pluginMap,屬性設置到setting
  3. 在Webview類裏面,加載index.html,index.html裏面加載cordova.js、開始初期化


JS側

  1. 加載cordova.js時、內部的事件設置模塊,NATIVE交互模塊,初期化模塊,插件加載
  2. 插件模塊是cordova_plugins.js文件定義的插件文件地址,文件名保存的MAP。
  3. deviceready事件發佈後,插件的API可以使用了。
  4. 插件API執行後,模塊MAP將插件文件加載,執行exec函數。
  5.  在index.html裏面添加一個空的iframe、指定src=gap://ready,通知到Nativie側。



Cordova本體的各個組的構造圖



說明
Staging組JS側的組。平臺不同,cordova.js和config.xml寫法不同
Plugins組Native側的插件組。添加的插件放在這個組
Classes組app啓動的appDelegate以及MainViewController類放置的組
CordovaLib組Cordova的核心類、JS,Native之間通信、整體控制類放置的組


Cordova本體JS與Native通信類

JS側:

function(全局函數,JS加載的時候被執行)                
cordova(基本模塊,所有的JS模塊在這裏面定義)

exec(JS和Native的窗口)                            
Channel(pub-sub定義、document/window#EventListener定義)
pluginloader(插件加載模塊)                                    

Native側:


CDVCommandQueue(插件API隊列)    
CDViewController(全體控制類)
CDVCommandDelegateImpl(API控制類)                
CDVPlugin(所有的插件的父類)




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章