一蚓耽、非引入JsBridge或WebViewJavascriptBridge庫(kù)的方案
1渠牲、H5與iOS/Android的通信方式
H5 webview與iOS通信
① 原生iOS調(diào)用js的方法(前端工程師可簡(jiǎn)單理解,掛載在windows對(duì)象下的js方法iOS原生都可以調(diào)用觸發(fā))
原生iOS可以訪問webview全局對(duì)象(windows對(duì)象下個(gè)的屬性)步悠,所以當(dāng)我們要讓iOS調(diào)用我們js的某些方法的可以在window下添加一個(gè)jsBridge對(duì)象签杈,里面可以定義給iOS調(diào)用的一些js方法。
②Js調(diào)用原生iOS(OC或Swift)方法
反過來鼎兽,JS調(diào)用原生iOS并沒有現(xiàn)成的API可以直接拿過來使用答姥,而是間接的利用一些方法來實(shí)現(xiàn)---->利用ios的UIWebview組件的特性铣除,在UIWebview內(nèi)發(fā)起的所有的網(wǎng)絡(luò)請(qǐng)求,都可以通過delegate函數(shù)在native層得到通知踢涌。簡(jiǎn)單點(diǎn)說就是我們H5頁(yè)面url路徑的跳轉(zhuǎn)請(qǐng)求,原生iOS這邊都可以抓到序宦,利用此特點(diǎn)我們可以像在get請(qǐng)求URL后面帶參數(shù)一樣帶參數(shù)讓原生iOS去取到睁壁。(利用url的這個(gè)過程需要前端和原生這邊約定好這個(gè)url的格式,例如:jsbridge://methodName?param1=value1¶m2=value2互捌,只要以jsbridge://開頭的地址就不要讓webview進(jìn)行頁(yè)面的跳轉(zhuǎn)潘明,轉(zhuǎn)而執(zhí)行相應(yīng)的邏輯,原生可以把要傳給vebview的某個(gè)數(shù)據(jù)掛在到window下的某個(gè)屬性上秕噪,js通過window.屬性名取到原生傳來的數(shù)據(jù))
上面提到的url的跳轉(zhuǎn)讓原生去攔截的方案钳降,js這邊實(shí)現(xiàn)方式有兩種:
①window.location.href
②利用頁(yè)面中嵌套的iframe的url(將iframe的長(zhǎng)寬都設(shè)為很小或者0,取到數(shù)據(jù)后再移除這個(gè)iframe)
建議使用②iframe的方式腌巾,因?yàn)槿绻覀冞B續(xù)多次修改window.location.href的值遂填,在Native層只能接收到最后一次請(qǐng)求,前面的請(qǐng)求都會(huì)被忽略掉澈蝙。
H5 webview與Android通信
1吓坚、目前js有三種調(diào)用原生Android的方式:
① 和上面Js調(diào)用原生iOS(OC或Swift)方法一樣,通過schema方式灯荧,Native使用shouldOverrideUrlLoading方法對(duì)url協(xié)議進(jìn)行解析礁击。這種js的調(diào)用方式與ios的一樣,使用iframe來調(diào)用native代碼逗载。(原理和使用方式與上面講的iOS攔截url的一樣哆窿,建議ios和android端都采用此方式,那么前端也將方便做兼容些)
② 往webview里面注入方法厉斟,前端角度理解就是Android創(chuàng)建了一個(gè)方法挚躯,添加到我們js的window對(duì)象里面了,直接調(diào)用就可以觸發(fā)原生的方法擦秽,如下代碼:
③ 使用prompt秧均、console.log、alert等方式号涯,這三個(gè)方法對(duì)js里是屬于原生的目胡,例如當(dāng)我們js代碼中使用alert(data)時(shí),原生這邊可以抓到data數(shù)據(jù)链快,然后它們進(jìn)行相應(yīng)的操作誉己,一般我們使用prompt,因?yàn)檫@個(gè)在js代碼里面使用的很少域蜗,用來和native通訊副作用較少巨双。
2噪猾、原生Android調(diào)用javascript方法通過在android代碼里使用webview的loadUrl進(jìn)行調(diào)用。
2袱蜡、js調(diào)用Native方法的封裝,兼容安卓和ios慢宗,供參考
二坪蚁、引入JsBridge(安卓)或WebViewJavascriptBridge(iOS)庫(kù)的方案
安卓端的JsBridge: ? ?https://github.com/lzyzsd/JsBridge
iOS端的WebViewJavascriptBridge: ?https://github.com/marcuswestin/WebViewJavascriptBridge
實(shí)際項(xiàng)目中有相當(dāng)一部分的原生內(nèi)嵌H5頁(yè)面混合開發(fā)的項(xiàng)目采用這個(gè)方案,使用上來說也很簡(jiǎn)單镜沽,其實(shí)就是對(duì)上面第一部分講的幾種實(shí)現(xiàn)原生與H5頁(yè)面通信方式的一個(gè)封裝敏晤。開發(fā)中安卓和iOS要分別引入JsBridge或者WebViewJavascriptBridge,Native這邊代碼參照官上面的github地址的代碼去配置缅茉,下面我僅以前端的角度來講解如何用代碼去實(shí)現(xiàn):
① ?首先安卓嘴脾、iOS、web前端三方要在一起定義好需要使用的接口的方法名及傳遞的參數(shù)蔬墩,三方統(tǒng)一译打,由于h5這邊是要實(shí)現(xiàn)一套代碼和Native兩方通信,所以如果可以的話由前端來定義各個(gè)方法及傳遞的方式拇颅,原則上來說扶平,web前端這邊是作為需求方的,我們定義好方法iOS和安卓設(shè)置此方法讓我們調(diào)用蔬蕊。(當(dāng)然我們也可以注冊(cè)方法结澄,讓Native來調(diào)用我們的方法)
②iOS和安卓端的代碼不羅列,基本思路就是他們要用registerHandler注冊(cè)一個(gè)方法岸夯,js這邊通過callHandler來調(diào)用這個(gè)方法麻献,同時(shí)js這邊也可以用registerHandler注冊(cè)一個(gè)方法,Native端通過callHandler來調(diào)用猜扮。下面的代碼以我用的react框架來寫勉吻。
特別說明一下:js中與Native通信的所有方法的注冊(cè)和調(diào)用都必須包裹在下圖的setupWebVie wJavascriptBridge函數(shù)里面。