hybrid設計之Native和H5交互原理

本人最近在研究hybrid的實現原理且讀了一些源碼 僅限前端js的 因此非前端或非hybrid模式的童鞋能夠繞過~javascript

首先簡介下url scheme

手機APP都有一個沙盒,能夠註冊本身的URL Scheme。咱們能夠經過系統的OpenURL來打開該app,並能夠傳遞一些參數。例如:
CtripWireless://打開攜程App
weixin:// 打開微信前端

目前大部分hybrid設計都是沿用JSBridge的,在不一樣的平臺經過不一樣的native層實現,在各自平臺下完成編譯。java

什麼是JSBridge?

顧名思義,JSBridge就是定義Native和JS的通訊,Native只經過一個固定的橋對象調用JS,JS也只經過固定的橋對象調用Native,基本原理是:git

H5->經過某種方式觸發一個url->Native捕獲到url,進行分析->原生作處理->Native調用H5的JSBridge對象傳遞迴調。github

圖片描述

實現思路

首先須要在全局對象Global下新建一個Bridge對象,實現如下3個方法:web

  1. jsCallNative(method, param, callback): h5主動調用native
  2. nativeCallback(param): native主動調用h5
  3. listenToNativeEmitMessage(msg, callback): h5註冊函數供Native調用

jsCallNative

  1. 判斷是否有回調函數callback,有就生成一個sequenceId,並將id和對應callback添加進入回調函數集合responseCallbacks中

(Reason:Js函數不能跨語言傳遞,Native沒法識別,但字符串/數字能夠。使用自增加的sequenceId代替callback函數,傳遞給Native,Bridge內部記錄一個全局對象responseCallbacks,記錄sequenceId和callback函數之間的mapping關係。傳遞給Native的是sequenceId,Native處理完成以後,返回的時候,都帶上對應的sequenceId。Bridge收到回調以後,根據sequenceId,取出對應的callback函數,而後調用。)api

  1. 將傳參拼接轉換成url,如schema://forward?param={foo:1}&sequenceId=1
  2. 使用一個隱藏的iframe來觸發scheme

    圖片描述

  3. Native監聽url變化,因爲這裏是Native的實現就不贅述了,值得注意的是這裏若是有callback回調,須要帶上參數sequenceId,與主動調用h5的參數是有區別的

圖片描述

nativeCallback

這裏承接上個方法最後提到的Native主動調用h5
圖片描述微信

附上代碼網絡

圖片描述

能夠看到,若是存在msg也就是function名,直接調用msgListenerList[msg](data);否則就是執行回調responseCallbacks[sequenceId](data),若是Native調用的api是h5沒有註冊的,h5頁面上會有對應的錯誤提示'Error NativeCallback: blabla'app

這個msgListenerList是哪來的呢?看最後個方法

listenToNativeEmitMessage

附上代碼

listenToNativeEmitMessage: function(msg, callback) {
  msg && callback && msgListenerList.push({emitMessageName: callback});
}

例如Native監聽到網絡狀態變動,你們常常會遇到,在wifi看視頻時忽然切成4g了須要提醒用戶

Bridge.listenToNativeEmitMessage('networkStateChange', function(data){
  console.log('network type: ' + data.networkType);
});

結語

大概的流程就這些,本身也是初學者,查了不少資料,如有錯誤但願指正~
附上個人代碼: webview-js-bridge

相關文章
相關標籤/搜索