本文不是介紹WebViewJavascriptBridge怎么使用的文章伊者,需要了解可以去參考Github上的Demo
本文主要解決h5端在setupWebViewJavascriptBridge
之后調(diào)用客戶端方法刀脏,有一段時間不生效的問題。之前的我們h5端的解決方案是在方法調(diào)用的時候加400ms
左右的延遲颗品,后來發(fā)現(xiàn)有些安卓機型即使加了400ms
的延遲依然無法調(diào)起客戶端的方法苍碟,到此發(fā)現(xiàn)延時調(diào)用這個事情不靠譜,遂尋找更好的解決方案稠集。
這時候去看了WebViewJavascriptBridge
的源碼,發(fā)現(xiàn)無論是安卓還是iOS在setup
的時候都會進行一系列注冊方法以及WebViewJavascriptBridge
掛載到window
對象下面饥瓷,只不過在掛載的過程中iOS更快剥纷,安卓比較慢見下圖對比:
第一個日期打印的是我調(diào)用客戶端方法的時間,第二個是當(dāng)WebViewJavascriptBridge
掛載完成的時間呢铆。iOS只需要幾到十幾ms晦鞋,但是安卓比較好的機型也需要150ms
以上,更差的機器400ms以上這就解釋了為什么有的安卓手機延時不生效的原因棺克。這是內(nèi)核的差異產(chǎn)生的悠垛,假如我們要用這個類庫就要沒辦法繞開這一步。
這個時候我就去翻了官方給的demo,發(fā)現(xiàn)這個庫是ios專有庫娜谊,并沒有安卓版本确买,應(yīng)該是哪個大佬仿寫了一套安卓的庫,因為太像了所以大家以為是一家的纱皆,ios類庫給的html端使用方法如下:
setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
window.WVJBCallbacks = [callback];
let WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'https://__bridge_loaded__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function() { document.documentElement.removeChild(WVJBIframe); }, 0);
}
//在html頁面調(diào)用
setupWebViewJavascriptBridge((bridge) => {
//someCode();
});
安卓端給的html頁面的demo如下:
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
document.addEventListener(
'WebViewJavascriptBridgeReady'
, function() {
callback(WebViewJavascriptBridge)
},
false
);
}
//在html頁面調(diào)用
setupWebViewJavascriptBridge((bridge) => {
//someCode();
});
看到這里不知道大家有沒有看明白湾趾,兩端bridge掛在成功之后,ios是通過執(zhí)行回調(diào)函數(shù)通知h5派草,安卓是通過發(fā)一個WebViewJavascriptBridgeReady事件搀缠,我們必須監(jiān)聽這個事件才能知道什么時候執(zhí)行,具體使用大家可以參考Android 和 IOS 使用 WebViewJavascriptBridge 進行交互方法
還有一種方法通過修改源碼統(tǒng)一兩端處理方法,在安卓端搜索WebViewJavascriptBridgeReady加上callback的回調(diào)澳眷,整個代碼如下:
var doc = document;
_createQueueReadyIframe(doc);
_createQueueReadyIframe4biz(doc);
var readyEvent = doc.createEvent('Events');
readyEvent.initEvent('WebViewJavascriptBridgeReady');
readyEvent.bridge = WebViewJavascriptBridge;
doc.dispatchEvent(readyEvent);
//安卓端需要添加如下代碼
setTimeout(_callWVJBCallbacks, 0);
function _callWVJBCallbacks() {
var callbacks = window.WVJBCallbacks;
delete window.WVJBCallbacks;
for (var i=0; i<callbacks.length; i++) {
callbacks[i](WebViewJavascriptBridge);
}
}
此時修改h5端代碼,由于都添加了callback回調(diào)的代碼胡嘿,所以只需要寫一套邏輯就可以了:
setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
window.WVJBCallbacks = [callback];
let WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'https://__bridge_loaded__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function() { document.documentElement.removeChild(WVJBIframe); }, 0);
}
//在html頁面調(diào)用
setupWebViewJavascriptBridge((bridge) => {
//someCode();
});