webview-bridge

在实现游戏内嵌直播平台的时候, 有些需求需要与游戏本体进行互动, 如关闭游戏音乐或调用游戏内接口等, 项目内旧版的接口调用方式是使用原生注入 js 接口来提供 js 调用, 这样新增接口的成本较高, 所以在调研过后决定和客户端同学一起将协议换成拦截url加载

  • webview内调用时候自动生成callbackId并注入到全局, 客户端处理完事件后调用此callback进行回调
  • 约定好返回值的数据结构, 客户端可以做到统一处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
const invokes = {};
let invokeId = 1;

function removeInvoke(invoke) {
window[invoke.callback] = null;
if (invoke.iframe) {
document.body.removeChild(invoke.iframe);
}
delete invokes[invoke.callback];
}

function invokeNative(func, params, onSuccess, onError) {
const invoke = {
func: func,
callback: 'webviewToNativeCallback' + invokeId,
params: params,
};
const iframe = document.createElement('iframe');
iframe.src = 'webview://' + encodeURIComponent(JSON.stringify(invoke));
iframe.className = 'native-iframe';
invoke.iframe = iframe;
invokes[invoke.callback] = invoke;
window[invoke.callback] = function (res) {
if (res && res.errno) {
console.log(res);
onError && onError(res);
} else {
onSuccess && onSuccess(res);
}
removeInvoke(invoke);
};
setTimeout(() => {
// 移除iframe后某些地方调用会有问题
// document.body.removeChild(invoke.iframe);
invoke.iframe = null;
}, 1000);
document.body.appendChild(iframe);
invokeId++;
}

export function callGameFunction() {
invokeNative('callGameFunction');
}

export default invokeNative;
作者

Mosby

发布于

2018-03-15

许可协议

评论