摘要:調(diào)用安卓后回調(diào)不成功,收不到返回的消息這個問題其實上有,這是安卓版本沒有解決的問題,最新的代碼已經(jīng)解決了。解決辦法是安卓需要引入最新的的代碼,而不要使用版本的代碼。
WebView與APP交互
WebView與APP交互,即網(wǎng)頁通過JSBrige調(diào)用APP的功能,APP也可以通過JSBrige調(diào)用網(wǎng)頁提供的方法。最近剛好接觸到這一塊,記錄一下前端側(cè)的實際操作過程,這篇文章適合還沒接觸過這一塊的同學(xué)們,這里不講原理,直接開始實戰(zhàn)的過程。
準(zhǔn)備工作與客戶端同學(xué)溝通好使用的JSBrige庫,我這里使用的是下面這兩個庫:
iOS(1.1w+ Star): https://github.com/marcuswestin/WebViewJavascriptBridge
Android(6k+ Star): https://github.com/lzyzsd/JsBridge
Star數(shù)量比較高,使用的企業(yè)也比較多,所以還是比較可靠的,可以在它們的文檔中示例代碼。
注意: github上有很多這樣的庫,但最好配套使用,即iOS和Android注入的jsBrige名稱一致,我們前端使用時比較方便統(tǒng)一。開發(fā)步驟 1. 統(tǒng)一封裝APP注入的JSBrige
ios和android注入的jsbrige可能會有些差異,所以在使用前我們需要抹平不同客戶端的差異。
如果app的同學(xué)使用了上面說的庫,安卓和iOS會在WebView中的window下注入一個WebViewJavascriptBridge的對象,iOS有可能是注入WVJBCallbacks的數(shù)組,也有可能需要通過iframe來注入。iOS的文檔中給出了一個兼容的示例代碼:
function setupWebViewJavascriptBridge(callback) { if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); } if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); } window.WVJBCallbacks = [callback]; var WVJBIframe = document.createElement("iframe"); WVJBIframe.style.display = "none"; WVJBIframe.src = "https://__bridge_loaded__"; document.documentElement.appendChild(WVJBIframe); setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0) }
我們可以直接使用上面的代碼,為了使用方便,在頁面onload后,我們將這個函數(shù)掛在window下:
window.onload = function () { function setupWebViewJavascriptBridge(callback) { if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); } if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); } window.WVJBCallbacks = [callback]; var WVJBIframe = document.createElement("iframe"); WVJBIframe.style.display = "none"; WVJBIframe.src = "https://__bridge_loaded__"; document.documentElement.appendChild(WVJBIframe); setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0) } window.setupWebViewJavascriptBridge = setupWebViewJavascriptBridge }
window.setupWebViewJavascriptBridge這個函數(shù),就是我們所說的JSBridge,即WebView與APP交互的橋梁。
2. JS調(diào)用APP的方法APP端的同學(xué)需要先用庫提供的方法在APP端實現(xiàn)一個方法,方法名比如:playMusic(musicId),可以傳遞參數(shù)musicId,表示讓APP開始播放某一首音樂。js調(diào)用時如:
window.setupWebViewJavascriptBridge(function (bridge) { bridge.callHandler("playMusic", { musicId: 1 }, function (data) { console.log("app觸發(fā)成功了,音樂正在播放。。。APP回調(diào)返回的數(shù)據(jù):", data) }) })
上面相當(dāng)于向app發(fā)起了一個playMusic請求,app收到請求后,執(zhí)行相關(guān)的動作,然后可以callback,網(wǎng)頁可以拿到回調(diào)并繼續(xù)做相關(guān)動作(需要的話)。
3. APP調(diào)JS提供的方法同樣的道理,若想APP能調(diào)用JS提供的方法,JS中要先注冊這個方法,方法名比如stateChange(state),JS注冊方法:
window.setupWebViewJavascriptBridge(function (bridge) { bridge.registerHandler("stateChange", function (data, responseCallback) { console.log("收到APP請求stateChange事件,請求的數(shù)據(jù)是:", data) // 可以返回給app一個回調(diào) responseCallback("朕已經(jīng)收到APP愛卿的請求了,且退下!") }) })
到這里,WebView與app的交互其實就完成了,就是這么簡單。
注意事項 1. window.onload時就callHandler可能不成功一般在Android中會出現(xiàn)這個問題,這是因為APP注入的WebViewJavascriptBridge還不存在,JS就調(diào)用其中的方法了,所以就會沒有效果。而Android的庫也給出了這個注意事項,所以得這樣寫:
window.onload = function () { function registerAppEvent () { window.setupWebViewJavascriptBridge(function (bridge) { bridge.registerHandler("stateChange", function (data, responseCallback) { console.log("收到APP請求,請求的數(shù)據(jù)是:", data) // 可以返回給app一個回調(diào) responseCallback("朕已經(jīng)收到APP愛卿的請求了,且退下!") }) }) } // 兼容寫法 if (window.WebViewJavascriptBridge) { registerAppEvent() } else { document.addEventListener( "WebViewJavascriptBridgeReady" , function() { registerAppEvent() }, false ) } }
但這里沒有考慮到iOS的情況,在最新的iOS中WebViewJavascriptBridge可能是不存在的,所以上面寫法registerAppEvent()在iOS可能無法執(zhí)行。為了避免多次注入事件,我這里用了setTimeout,兼容兩端的流程:
let isInitBridgeEvent = false // 作為是否已注冊過事件的標(biāo)記 if (window.WebViewJavascriptBridge) { registerAppEvent() isInitBridgeEvent = true } else { document.addEventListener( "WebViewJavascriptBridgeReady", function () { registerAppEvent() isInitBridgeEvent = true }, false ) // 如果還沒注冊則再注冊一次 setTimeout(() => { if (!isInitBridgeEvent) { registerAppEvent() isInitBridgeEvent = true } }, 100)
這坨代碼寫的很挫,讓我尷尬癌都犯了,有沒有熱心的小伙伴幫我優(yōu)化下寫法[送花花]。
2. js調(diào)用安卓后callback回調(diào)不成功,js收不到app返回的消息這個問題其實github上有issue,這是安卓1.0.4版本沒有解決的問題,最新的代碼已經(jīng)解決了。
解決辦法是:安卓需要引入最新的master的代碼,而不要使用1.0.4版本的代碼。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/101855.html
摘要:一原理篇下面分別介紹和與的底層交互原理在講解原理之前,首先來了解下的組件,先來看一下蘋果官方的介紹上面的意思是說是一個可加載網(wǎng)頁的對象,它有瀏覽記錄功能,且對加載的網(wǎng)頁內(nèi)容是可編程的。 做過混合開發(fā)的很多人都知道Ionic和PhoneGap之類的框架,這些框架在web基礎(chǔ)上包了一層Native,然后通過Bridge技術(shù)使得js可以調(diào)用視頻、位置、音頻等功能。本文就是介紹這層Bridge...
閱讀 3834·2021-09-06 15:00
閱讀 2171·2019-08-30 15:53
閱讀 3277·2019-08-23 16:44
閱讀 944·2019-08-23 15:19
閱讀 1390·2019-08-23 12:27
閱讀 4187·2019-08-23 11:30
閱讀 581·2019-08-23 10:33
閱讀 369·2019-08-22 16:05