首頁>技術>

一 、jsbridge 定義

JSBridge 是一種 JS 實現的 Bridge,連線著橋兩端的 Native 和 H5。它在 APP 內方便地讓 Native 呼叫 JS,JS 呼叫 Native ,是雙向通訊的通道。JSBridge 主要提供了 JS 呼叫 Native 程式碼的能力,實現原生功能如檢視本地相簿、開啟攝像頭、指紋支付等。

二、JSBridge 用途

JSBridge 就像其名稱中的『Bridge』的意義一樣,是 Native 和非 Native 之間的橋樑,它的核心是 構建 Native 和非 Native 間訊息通訊的通道,而且是 雙向通訊的通道。

雙向通訊的通道:

1) JS 向 Native 傳送訊息: 呼叫相關功能、通知 Native 當前 JS 的相關狀態等。

2) Native 向 JS 傳送訊息: 回溯呼叫結果、訊息推送、通知 JS 當前 Native 的狀態等。

H5與Native互動如下圖:

三、JSBridge 的實現原理

JavaScript 是執行在一個單獨的 JS Context 中(例如,WebView 的 Webkit 引擎、JSCore)。由於這些 Context 與原生執行環境的天然隔離,我們可以將這種情況與 RPC(Remote Procedure Call,遠端過程呼叫)通訊進行類比,將 Native 與 JavaScript 的每次互相呼叫看做一次 RPC 呼叫。

在 JSBridge 的設計中,可以把前端看做 RPC 的客戶端,把 Native 端看做 RPC 的伺服器端,從而 JSBridge 要實現的主要邏輯就出現了:通訊呼叫(Native 與 JS 通訊) 和控制代碼解析呼叫。

四、JSBridge 的通訊原理

一、JavaScript 呼叫 Native的方式

JavaScript 呼叫 Native 的方式,主要有兩種:注入 API 和 攔截 URL SCHEME。

1、注入API

注入 API 方式的主要原理是,通過 WebView 提供的介面,向JavaScript 的 Context(window)中注入物件或者方法,讓 JavaScript 呼叫時,直接執行相應的 Native 程式碼邏輯,達到 JavaScript 呼叫 Native 的目的。

對於 iOS 的 UIWebView,例項如下:

JSContext *context = [uiWebView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; context[@"postBridgeMessage"] = ^(NSArray<NSArray *> *calls) { // Native 邏輯 }; 前端呼叫方式: window.postBridgeMessage(message); 
2、攔截 URL SCHEME

先解釋一下 URL SCHEME:URL SCHEME是一種類似於url的連結,是為了方便app直接互相呼叫設計的,形式和普通的 url 近似,主要區別是 protocol 和 host 一般是自定義的,

例如: qunarhy://hy/url?url=ymfe.tech,protocol 是 qunarhy,host 則是 hy。

攔截 URL SCHEME 的主要流程是:Web 端通過某種方式(例如 iframe.src)傳送 URL Scheme 請求,之後 Native 攔截到請求並根據 URL SCHEME(包括所帶的引數)進行相關操作。

在時間過程中,這種方式有一定的缺陷:

1) 使用 iframe.src 傳送 URL SCHEME 會有 url 長度的隱患。

2) 建立請求,需要一定的耗時,比注入 API 的方式呼叫同樣的功能,耗時會較長。

因此:JavaScript 呼叫 Native 推薦使用注入 API 的方式

二、Native 呼叫 JavaScript 的方式

相比於 JavaScript 呼叫 Native, Native 呼叫 JavaScript 較為簡單,直接執行拼接好的 JavaScript 程式碼即可。

從外部呼叫 JavaScript 中的方法,因此 JavaScript 的方法必須在全域性的 window 上。

對於 iOS 的 UIWebView,示例如下:

result = [uiWebview stringByEvaluatingJavaScriptFromString:javaScriptString]; * javaScriptString為JavaScript 程式碼串 

對於 iOS 的 WKWebView,示例如下:

[wkWebView evaluateJavaScript:javaScriptString completionHandler:completionHandler]; 
三、通訊原理總結通訊原理是 JSBridge 實現的核心

1)JavaScript 呼叫 Native 推薦使用 注入 API 的方式(iOS6 忽略,Android 4.2以下使用 WebViewClient 的 onJsPrompt 方式)。

2)Native 呼叫 JavaScript 則直接執行拼接好的 JavaScript 程式碼即可。

四、JSBridge 介面實現

JSBridge 的介面主要功能有兩個:呼叫 Native(給 Native 發訊息) 和 被 Native 呼叫(接收 Native 訊息)。因此,JSBridge 可以設計如下:

window.JSBridge = {   // 呼叫 Native   invoke: function(msg) {     // 判斷環境,獲取不同的 nativeBridge     nativeBridge.postMessage(msg);   },   receiveMessage: function(msg) {     // 處理 msg   } }; 

在上面的文章中,提到過 RPC 中有一個非常重要的環節是 控制代碼解析呼叫 ,這點在 JSBridge 中體現為 控制代碼與功能對應關係。同時,我們將控制代碼抽象為 橋名(BridgeName),最終演化為 一個 BridgeName 對應一個 Native 功能或者一類 Native 訊息。基於此點,JSBridge 的實現可以優化為如下:

window.JSBridge = {   // 呼叫 Native   invoke: function(bridgeName, data) {   // 判斷環境,獲取不同的 nativeBridge     nativeBridge.postMessage({       bridgeName: bridgeName,       data: data || {}     });   },   receiveMessage: function(msg) {     var bridgeName = msg.bridgeName,     data = msg.data || {};   // 具體邏輯   } }; 

對於 JSBridge 的 Callback ,其實就是 RPC 框架的回撥機制。當然也可以用更簡單的 JSONP 機制解釋:

當傳送 JSONP 請求時,url 引數裡會有 callback 引數,其值是 當前頁面唯一 的,而同時以此引數值為 key 將回調函式存到 window 上,隨後,伺服器返回 script 中,也會以此引數值作為控制代碼,呼叫相應的回撥函式。

整體流程:

在 Native 端配合實現 JSBridge 的 JavaScript 呼叫 Native 邏輯也很簡單,主要的程式碼邏輯是:接收到 JavaScript 訊息 => 解析引數,拿到 bridgeName、data 和 callbackId => 根據 bridgeName 找到功能方法,以 data 為引數執行 => 執行返回值和 callbackId 一起回傳前端。

Native呼叫 JavaScript 也同樣簡單,直接自動生成一個唯一的 ResponseId,並存儲控制代碼,然後和 data 一起傳送給前端即可。

五、JSBridge 如何引用

對於 JSBridge 的引用,常用有兩種方式,各有利弊。

1) 由 Native 端進行注入

注入方式和 Native 呼叫 JavaScript 類似,直接執行橋的全部程式碼。

優點:橋的版本很容易與 Native 保持一致,Native 端不用對不同版本的 JSBridge 進行相容;與此同時,

缺點:注入時機不確定,需要實現注入失敗後重試的機制,保證注入的成功率,同時 JavaScript 端在呼叫介面時,需要優先判斷 JSBridge 是否已經注入成功。

2) 由 JavaScript 端引用

直接與 JavaScript 一起執行。與由 Native 端注入正好相反。

優點:JavaScript 端可以確定 JSBridge 的存在,直接呼叫即可;

缺點:如果橋的實現方式有更改,JSBridge 需要相容多版本的 Native Bridge 或者 Native Bridge 相容多版本的 JSBridge。

最新評論
  • 1 #

    沒有程式碼理解的不深

  • 2 #

    我想在跑車裡,想要一輛法拉利

  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Cocos整合AGC效能管理(二)-- 效能管理SDK整合