JSBridge通信原理
简单代码实现,封装成JSBridge类
const isAndroid = window.navigator.userAgent.indexOf('Android') !== -1
function possNativeMessage(message){
if(isAndroid){
window.JSOriginBridge.postMessage(message);
}else {
window.webkit.messageHandlers.JSOriginBridge.postMessage(message);
}
}
/* 向 Native 发布事件 */
function publishNativeMessage(params){
const message = {
eventType:'publish',
data:params
}
possNativeMessage(message)
}
/* 触发 Native 方法, 触发回调函数 */
function invokeNativeEvent(name,params,callbackId){
const message = {
eventType:'invoke',
type:name,
data:params,
callbackId
}
possNativeMessage(message)
}
class JSBridge {
/* 保存 */
eventHandlers = new Map()
responseCallbacks = new Map()
callbackID = 0
constructor() {
window._handleNativeCallback = this.handleNativeCallback.bind(this)
window._handleNativeEvent = this.handleNativeEvent.bind(this)
}
/* 向 native 发送消息 */
postMessage(params){
const data = JSON.stringify(params)
publishNativeMessage(data)
}
/* 向 native 发送消息,等待回调函数 */
invoke(name,payload,callback){
this.callbackID++
/* 将回调函数保存起来 */
this.responseCallbacks.set(this.callbackID,callback)
invokeNativeEvent(name,payload,this.callbackID)
}
/*
处理 native 调用 window 上的 _handleNativeCallback 方法。
当执行 invoke 回调的时候,执行该方法
*/
handleNativeCallback(jsonResponse){
const res = JSON.parse(jsonResponse)
const { callbackID,...params } = res
const callback = this.responseCallbacks.get(callbackID)
/* 取出回调函数并且执行 */
callback && callback(params)
/* 删除对应的回调函数 */
this.responseCallbacks.delete(callbackID)
}
/*
处理 native 调用 window 上的 _handleNativeEvent 方法。
处理绑定在 native 的事件
*/
handleNativeEvent(jsonResponse){
const res = JSON.parse(jsonResponse)
const { eventName,...params } = res
const callback = this.eventHandlers.get(eventName)
callback(params)
}
/* 绑定注册事件 */
registerEvent(name,callback){
this.eventHandlers.set(name,callback)
}
/* 解绑事件 */
unRegisterEvent(name){
this.eventHandlers.delete(name)
}
}
export default new JSBridge()
js端向native发布事件并执行回调函数
js端发送信号、数据、回调函数给native,native接受信号,处理完成以后返回数据并执行回调函数。
js端发送信号、数据、回调函数给native时,JSBridge记录储存回调函数。native接受信号、数据,执行相应的内部逻辑以后,执行预先挂载在window对象上的方法,并把数据和回调函数的id作为参数传入。此时预先挂载在window对象上的这个方法会通过回调函数的id找到该回调函数,把数据传入执行。
这就是一个完整流程。
native调用js函数
js端预先在window对象上绑定注册事件,native直接通过约定名找到并执行预先挂载在window对象上的方法。