開源代碼分析之Android/iOS Hybrid JSBridge框架

Hybrid開發是如今的主流形式,對於業務快速迭代的公司尤爲重要。曾將在鞋廠接觸了不少關於Hybrid的理念,在這裏分享一些Hybrid框架思想。前端

Hybrid框架包括Native與H5的通訊,WebView的管理等,這裏主要介紹通訊。java

文章主要分爲兩個部分,第一部分介紹Hybrid與H5通訊的幾種方式,第二部分分析了開源框架的具體作法。git

第一部分 Hybrid與H5通訊github

Hybrid與H5通訊實現方式有不少種,有基於url攔截的,也有基於prompt攔截的。web

最後分析的這個框架和PhoneGap同樣採用prompt攔截,但內部處理機制沒有PhoneGap複雜,暫時對PhoneGap不是徹底瞭解,就不裝B了。框架

H5與Native通訊,如今採用最多的方式是依賴中間過渡的WebView,其餘的不瞭解。異步

基於對Hybrid的瞭解,就分H5調用Native和Native通知H5。下面來細說這兩點。函數

1.H5調用Nativeurl

這種方式主要是須要Native宿主環境經過WebView來提供一些H5調用的接口方法。spa

若是採用url攔截的,也就是經過一個隱藏iframe或者修改location發起請求,好比bridge://service/method?params&callback,能夠在webview加載時獲取到該url,並針對url信息分析對應到Native中的某個service類的某個method方法。

若是採用prompt攔截的,好比prompt(service,method,params,callback),原理與url方式差很少,不過是在H5發起prompt請求,webview截獲到這個prompt中的參數,調用Native中對應的某個service類的某個method方法。

這兩種方式通常會與一個Bridge.js配合,Bridge.js封裝了bridge://service/method?params&callback的構造,或prompt(service,method,params,callback)的請求,提供H5良好的訪問接口。

當H5端調用某個方法時,將對應的參數和回調封裝成url或prompt的形式,而後請求webview,webview截獲url或prompt,請求本地服務獲取數據後,經過註冊在window對象上的callback將請求結果返回給H5。

這兩種方式的開源庫可參考:jsbridge-to-cocoa(url+bridge.js)   safe-java-js-webview-bridge(prompt)

針對這兩種基本方式可擴展,好比某所是直接採用了url+bridge這種方式,而鞋廠則針對性的作出些調整(後面針對性的介紹),還有後面介紹的safe-java-js-webview-bridge則與PhoneGap相似,消除了H5對Bridge.js的可見性,經過反射Native提供的service自動構造Bridge.js並注入到WebView中。

至於上面兩種方式及其擴展的好壞之分,主要看設計上如何使H5調用變得簡單則好,儘可能下降Native與H5的耦合,分清構造Bridge.js的職責。

2.Native通知H5

這種方式主要是H5將某些監聽事件(如webview下拉刷新、native推送)綁定到window上,當Native須要調用H5時,能夠經過webview中註冊的這些事件回調通知H5。

Native通知H5的方式比H5調用Native來的簡單,不過在項目中如何將兩者結合起來,提供統一的調用接口則須要良好的設計。

若是須要完成H5與Native的相互訪問,基本上採用上面兩種方法便可完成,但若是要封裝的對H5調用接口友好,則須要在設計上下功夫,這就是仁者見仁智者見智的事情。

後續會分別補充某所和鞋廠各自對Bridge.js的封裝思想。//TODO

第二部分 開源框架分析

1.iOS開源框架 jsbridge-to-cocoa

先來看看jsbridge-to-cocoa的源碼結構,由於不存在太多的設計思想,僅僅是上述方式的一個實現過程。

採用url攔截的方式實現H5調用Native,但調用後沒有回調的過程,並且還未實現Native通知H5的過程。(可能理解有誤差,大神勿噴)

下面說說這個框架的基本思想,Bridge.js中包含了供H5和Native使用的方法,分兩步:

1. H5經過調用AddObject添加請求的參數和回調,經過SendObject封裝的url來觸發webview攔截;

2. Native中的webview攔截後,會分析url中的請求參數,調用本地服務,完成本地功能後會調用Bridge提供的接口,調用H5的回調

下面直接看看時序圖,也比較易於理解。

注:描述過程和截圖中都含有紅色部分,是針對該框架的弱點提供的補充,便可保證H5訪問Native後能回調H5的過程。

2.Android開源框架 safe-java-js-webview-bridge

抽空看了了下safe-java-js-webview-bridge的源碼,整理了一份類之間的調用關係圖。

值得推薦的是這個庫屏蔽了H5對Bridge.js的可見性,並且Bridge.js是經過對Native中對外公開的類進行反射生成的,提升了複用性。

不過也有其缺點,Native提供給H5的方法都封裝在一個Bridge.js中,若是Native須要暴露給H5的功能模塊增多時,且須要按模塊進行細分時,Bridge.js則顯得有點模糊。

這個問題只須要對其原理熟悉,改形成支持多模塊的成本也不大。後續補充源碼鏈接,還在改造中。//TODO

注:這個庫中Bridge.js這個文件名是不存在的,可自行指定,這裏爲了方便理解,因此採用Bridge.js。

下面說說開源庫safe-java-js-webview-bridge的基本思路,分三步:

1.在native端編寫調用本地功能的class(如HostJsScope.java),在初始化WebviewChromeClient時根據該class(在JsCallJava構造函數中)反射動態生成js代碼;

2.將動態生成的js代碼經過webview.loadUrl觸發的onProgressChanged注入到webview中,供前端可調用;

3.在前端調用HostJsScope對應的接口,出發webview的onPrompt事件,進而調用本地HostJsScope方法,若是是同步且有返回值,經過prompt返回值返回,若是是異步,則反射調用JsCallback將數據返回前端。

先上圖,後面逐步分析調用關係。(因爲對UML時序圖不甚瞭解,原諒圖中的錯誤)

根據截圖能夠清晰的看到三個步驟的調用過程,若是有興趣的能夠拿源碼對比該截圖進行分析。

經過對以上兩個開源框架的分析,能夠理解H5調用Native並回調H5的通訊過程,但兩者都爲對Native通知H5的通訊實現,不過這部分實現也比較簡單。原理上面也解釋過了,經過截圖來描述下。

Hybrid框架中H5與Native相互通訊的過程基本如此,不過不少原理細節未作過多描述,若是興趣的同窗能夠留言一塊兒討論。

相關文章
相關標籤/搜索