H5與iOS/Android的通信方式(原生內嵌H5頁面通信模式淺析)---新增JsBridge和WebViewJavascriptBridge

一、非引入JsBridge或WebViewJavascriptBridge庫的方案

1、H5與iOS/Android的通信方式

H5 webview與iOS通信

① 原生iOS調用js的方法(前端工程師可簡單理解,掛載在windows對象下的js方法iOS原生都可以調用觸發)
原生iOS可以訪問webview全局對象(windows對象下個的屬性),所以當我們要讓iOS調用我們js的某些方法的可以在window下添加一個jsBridge對象,里面可以定義給iOS調用的一些js方法。

②Js調用原生iOS(OC或Swift)方法
反過來,JS調用原生iOS并沒有現成的API可以直接拿過來使用,而是間接的利用一些方法來實現---->利用ios的UIWebview組件的特性,在UIWebview內發起的所有的網絡請求,都可以通過delegate函數在native層得到通知。簡單點說就是我們H5頁面url路徑的跳轉請求,原生iOS這邊都可以抓到,利用此特點我們可以像在get請求URL后面帶參數一樣帶參數讓原生iOS去取到。(利用url的這個過程需要前端和原生這邊約定好這個url的格式,例如:jsbridge://methodName?param1=value1&param2=value2,只要以jsbridge://開頭的地址就不要讓webview進行頁面的跳轉,轉而執行相應的邏輯,原生可以把要傳給vebview的某個數據掛在到window下的某個屬性上,js通過window.屬性名取到原生傳來的數據)

上面提到的url的跳轉讓原生去攔截的方案,js這邊實現方式有兩種:
①window.location.href
②利用頁面中嵌套的iframe的url(將iframe的長寬都設為很小或者0,取到數據后再移除這個iframe)
建議使用②iframe的方式,因為如果我們連續多次修改window.location.href的值,在Native層只能接收到最后一次請求,前面的請求都會被忽略掉。

iframe方式前端代碼

H5 webview與Android通信

1、目前js有三種調用原生Android的方式:

① 和上面Js調用原生iOS(OC或Swift)方法一樣,通過schema方式,Native使用shouldOverrideUrlLoading方法對url協議進行解析。這種js的調用方式與ios的一樣,使用iframe來調用native代碼。(原理和使用方式與上面講的iOS攔截url的一樣,建議ios和android端都采用此方式,那么前端也將方便做兼容些)

② 往webview里面注入方法,前端角度理解就是Android創建了一個方法,添加到我們js的window對象里面了,直接調用就可以觸發原生的方法,如下代碼:

實例代碼

③ 使用prompt、console.log、alert等方式,這三個方法對js里是屬于原生的,例如當我們js代碼中使用alert(data)時,原生這邊可以抓到data數據,然后它們進行相應的操作,一般我們使用prompt,因為這個在js代碼里面使用的很少,用來和native通訊副作用較少。

2、原生Android調用javascript方法通過在android代碼里使用webview的loadUrl進行調用。

安卓中的代碼如上,需要被原生調用的js方法放全局

2、js調用Native方法的封裝,兼容安卓和ios,供參考


兼顧iOS和Android通信的js代碼

二、引入JsBridge(安卓)或WebViewJavascriptBridge(iOS)庫的方案

安卓端的JsBridge: ? ?https://github.com/lzyzsd/JsBridge
iOS端的WebViewJavascriptBridge: ?https://github.com/marcuswestin/WebViewJavascriptBridge

實際項目中有相當一部分的原生內嵌H5頁面混合開發的項目采用這個方案,使用上來說也很簡單,其實就是對上面第一部分講的幾種實現原生與H5頁面通信方式的一個封裝。開發中安卓和iOS要分別引入JsBridge或者WebViewJavascriptBridge,Native這邊代碼參照官上面的github地址的代碼去配置,下面我僅以前端的角度來講解如何用代碼去實現:
① ?首先安卓、iOS、web前端三方要在一起定義好需要使用的接口的方法名及傳遞的參數,三方統一,由于h5這邊是要實現一套代碼和Native兩方通信,所以如果可以的話由前端來定義各個方法及傳遞的方式,原則上來說,web前端這邊是作為需求方的,我們定義好方法iOS和安卓設置此方法讓我們調用。(當然我們也可以注冊方法,讓Native來調用我們的方法)

②iOS和安卓端的代碼不羅列,基本思路就是他們要用registerHandler注冊一個方法,js這邊通過callHandler來調用這個方法,同時js這邊也可以用registerHandler注冊一個方法,Native端通過callHandler來調用。下面的代碼以我用的react框架來寫。
特別說明一下
:js中與Native通信的所有方法的注冊和調用都必須包裹在下圖的setupWebVie wJavascriptBridge函數里面。


前端和Native通信方法外層包裹的固定代碼



最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容