本文不是介绍WebViewJavascriptBridge怎么使用的文章,需要了解可以去参考Github上的Demo
本文主要解决h5端在setupWebViewJavascriptBridge
之后调用客户端方法,有一段时间不生效的问题。之前的我们h5端的解决方案是在方法调用的时候加400ms
左右的延迟,后来发现有些安卓机型即使加了400ms
的延迟依然无法调起客户端的方法,到此发现延时调用这个事情不靠谱,遂寻找更好的解决方案。
这时候去看了WebViewJavascriptBridge
的源码,发现无论是安卓还是iOS在setup
的时候都会进行一系列注册方法以及WebViewJavascriptBridge
挂载到window
对象下面,只不过在挂载的过程中iOS更快,安卓比较慢见下图对比:
第一个日期打印的是我调用客户端方法的时间,第二个是当WebViewJavascriptBridge
挂载完成的时间。iOS只需要几到十几ms,但是安卓比较好的机型也需要150ms
以上,更差的机器400ms以上这就解释了为什么有的安卓手机延时不生效的原因。这是内核的差异产生的,假如我们要用这个类库就要没办法绕开这一步。
这个时候我就去翻了官方给的demo,发现这个库是ios专有库,并没有安卓版本,应该是哪个大佬仿写了一套安卓的库,因为太像了所以大家以为是一家的,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页面调用
setupWebViewJavascriptBridge((bridge) => {
//someCode();
});
安卓端给的html页面的demo如下:
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
document.addEventListener(
'WebViewJavascriptBridgeReady'
, function() {
callback(WebViewJavascriptBridge)
},
false
);
}
//在html页面调用
setupWebViewJavascriptBridge((bridge) => {
//someCode();
});
看到这里不知道大家有没有看明白,两端bridge挂在成功之后,ios是通过执行回调函数通知h5,安卓是通过发一个WebViewJavascriptBridgeReady事件,我们必须监听这个事件才能知道什么时候执行,具体使用大家可以参考Android 和 IOS 使用 WebViewJavascriptBridge 进行交互方法
还有一种方法通过修改源码统一两端处理方法,在安卓端搜索WebViewJavascriptBridgeReady加上callback的回调,整个代码如下:
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
此时修改h5端代码,由于都添加了callback回调的代码,所以只需要写一套逻辑就可以了:
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页面调用
setupWebViewJavascriptBridge((bridge) => {
//someCode();
});