前提-出现场景
- 使用机型为 Android 9,API 28
- 使用的 jsBridge 为 link
bug 描述
在页面加载前后如果连续多次调用原生的方法,会遇到回调参数未被调用的情况。
// 多次调用如下函数, 部分 callback 将不会被调用
window.WebViewJavascriptBridge.callHandler(api, parameter, callback);
复制代码
bug 的稳定复现方式
在页面加载时通过jsBridge和原生进行10次以上的数据交换。
出现的原因
查询所得
在多篇文章(1,2)中看到是因为 jsBridge 使用 iframe 的 src 变化 和 shouldOverrideUrlLoading 来实现原生与js的沟通导致的问题,而刷新 iframe 并不能保证 shouldOverrideUrlLoading 会被调用。
于是我们以此为假设进行验证
-
验证1: jsBridge 是否使用 iframe.src 的变化来进行js与原生的通讯
我们可以直接看看进行一次完整的通讯的调用过程。
//依据调用链
window.WebViewJavascriptBridge.callHandler(api, parameter, callback);
function callHandler(handlerName, data, responseCallback) {
_doSend(
{
handlerName: handlerName,
data: data
},
responseCallback
);
}
function _doSend(message, responseCallback) {
if (responseCallback) {
var callbackId = "cb_" + uniqueId++ + "_" + new Date().getTime();
responseCallbacks[callbackId] = responseCallback;
message.callbackId = callbackId;
}
sendMessageQueue.push(message);
//改变html内的iframe的src
messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + "://" + QUEUE_HAS_MESSAGE;
}
// 此时步骤转到原生层面
复制代码