注册

APP与H5通信-JsBridge

背景


在移动开发领域,原生应用嵌入网页(H5)可以实现一套代码多端使用,那么原生应用(APP)和网页(H5)之间的通信就非常重要。


JsBridge作为一种实现此类通信的工具,用于实现原生应用和嵌入其中的网页之间的通信。


H5与native交互,本质上来说就两种调用:



  1. JavaScript 调用 native 方法
  2. native 调用 JavaScript 方法

JavaScript调用native方法有两种方式:



  1. 注入,native 往 webview 的 window 对象中添加一些原生方法,h5可以通过注入的方法来调用 app 的原生能力
  2. 拦截,H5通过与 native 之间的协议发送请求,native拦截请求再去调用 app 原生能力

本文主要介绍H5端与App(android和ios)之间通信使用方式。


代码实现


实现步骤:


这段代码实现的是 APP(Android 和 iOS) 和 H5 之间的通信。这个通信过程主要依赖于 WebViewJavascriptBridge 这个桥接库。这里是具体的流程:



  1. 初始化 WebViewJavascriptBridge 对象:

    • 对于 Android,如果 WebViewJavascriptBridge 对象已经存在,则直接使用;如果不存在,则在 'WebViewJavascriptBridgeReady' 事件触发时获取 WebViewJavascriptBridge 对象。
    • 对于 iOS,如果 WebViewJavascriptBridge 对象已经存在,直接使用;如果不存在,则创建一个隐藏的 iframe 来触发 WebViewJavascriptBridge 的初始化,并在初始化完成后通过 WVJBCallbacks 回调数组来获取 WebViewJavascriptBridge 对象。


  2. 注册事件:

    提供了 callHandlerregisterHandler 两个方法,分别用于在 JS 中调用 APP 端的方法和注册供 APP 端调用的 JS 方法。


  3. 调用方法:

    当 APP 或 JS 需要调用对方的方法时,只需调用 callHandlerregisterHandler 方法即可。



const { userAgent } = navigator;
const isAndroid = userAgent.indexOf('android') > -1; // android终端

/**
* Android 与安卓交互时:
* 1、不调用这个函数安卓无法调用 H5 注册的事件函数;
* 2、但是 H5 可以正常调用安卓注册的事件函数;
* 3、还必须在 setupWebViewJavascriptBridge 中执行 bridge.init 方法,否则:
* ①、安卓依然无法调用 H5 注册的事件函数
* ①、H5 正常调用安卓事件函数后的回调函数无法正常执行
*
* @param {*} callback
*/

function androidFn(callback) {
if (window.WebViewJavascriptBridge) {
callback(window.WebViewJavascriptBridge);
} else {
document.addEventListener(
'WebViewJavascriptBridgeReady',
() => {
callback(window.WebViewJavascriptBridge);
},
false,
);
}
}

/**
* IOS 与 IOS 交互时,使用这个函数即可,别的操作都不需要执行
*/

function iosFn(callback) {
if (window.WebViewJavascriptBridge) { return callback(window.WebViewJavascriptBridge); }
if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
window.WVJBCallbacks = [callback];
const WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'https://__BRIDGE_LOADED__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(() => { document.documentElement.removeChild(WVJBIframe); }, 0);
}

/**
* 注册 setupWebViewJavascriptBridge 方法
* 之所以不将上面两个方法融合成一个方法,是因为放在一起,那么就只有 iosFuntion 中相关的方法体生效
*/

const setupWebViewJavascriptBridge = isAndroid ? androidFn : iosFn;

/**
* 这里如果不做判断是不是安卓,而是直接就执行下面的方法,就会导致
* 1、IOS 无法调用 H5 这边注册的事件函数
* 2、H5 可以正常调用 IOS 这边的事件函数,并且 H5 的回调函数可以正常执行
*/

if (isAndroid) {
/**
* 与安卓交互时,不调用这个函数会导致:
* 1、H5 可以正常调用 安卓这边的事件函数,但是无法再调用到 H5 的回调函数
*
* 前提 setupWebViewJavascriptBridge 这个函数使用的是 andoirFunction 这个,否则还是会导致上面 1 的现象出现
*/

setupWebViewJavascriptBridge((bridge) => {
console.log('打印***bridge', bridge);
// 注册 H5 界面的默认接收函数(与安卓交互时,不注册这个事件无法接收回调函数)
bridge.init((message, responseCallback) => {
responseCallback('JS 初始化');
});
});
}

export default {
// js调APP方法 (参数分别为:app提供的方法名 传给app的数据 回调)
callHandler(name, params, callback) {
setupWebViewJavascriptBridge((bridge) => {
bridge.callHandler(name, params, callback);
});
},

// APP调js方法 (参数分别为:js提供的方法名 回调)
registerHandler(name, callback) {
setupWebViewJavascriptBridge((bridge) => {
bridge.registerHandler(name, (data, responseCallback) => {
callback(data, responseCallback);
});
});
},
};

使用 JSBridge 总结:


1、跟 IOS 交互的时候,只需要且必须注册 iosFuntion 方法即可,不能在 setupWebViewJavascriptBridge 中执行 bridge.init 方法,否则 IOS 无法调用到 H5 的注册函数;


2、与安卓进行交互的时候



  • 使用 iosFuntion,就可以实现 H5 调用 安卓的注册函数,但是安卓无法调用 H5 的注册函数,
    并且 H5 调用安卓成功后的回调函数也无法执行
  • 使用 andoirFunction 并且要在 setupWebViewJavascriptBridge 中执行 bridge.init 方法,
    安卓才可以正常调用 H5 的回调函数,并且 H5 调用安卓成功后的回调函数也可以正常执行了

H5使用


h5获取app返回的数据:


jsBridge.callHandler('getAppUserInfo', { title: '首页' }, (data) => {
console.log('获取app返回的数据', data);
});

app获取h5返回的数据:


 jsBridge.registerHandler('getInfo', (data, responseCallback) => {
console.log('打印***get app data', data);
responseCallback('我是返回的数据');
});


两者都可通信,只要一方使用registerHandler注册了事件,另一方通过callHandler接受数据


总结


主要介绍了原生应用嵌入网页(H5)与APP(android和ios)之间的通信实现方法。


这个通信过程主要依赖于 WebViewJavascriptBridge 这个桥接库。通过在JavaScript中调用native方法和native调用JavaScript方法,实现APP和H5的互通。


主要通过提供了 callHandlerregisterHandler 两个方法,分别用于在 JS 中调用 APP 端的方法和注册供 APP 端调用的 JS 方法。


更简单方式: APP与H5通信-postMessage


参考资料:


ios-webview


android-webview


参考案例


作者:一诺滚雪球
来源:juejin.cn/post/7293728293768855587

0 个评论

要回复文章请先登录注册