在实现游戏内嵌直播平台的时候, 有些需求需要与游戏本体进行互动, 如关闭游戏音乐或调用游戏内接口等, 项目内旧版的接口调用方式是使用原生注入 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(() => { invoke.iframe = null; }, 1000); document.body.appendChild(iframe); invokeId++; }
export function callGameFunction() { invokeNative('callGameFunction'); }
export default invokeNative;
|