与flutter通信的jsbridge

1,389 阅读2分钟

引言

本文主要是简单叙述了如何实现一个与flutter通信的jsbridge。

js调用flutter

flutter需要用JavascriptChannel注册一个方法供js调用

JavascriptChannel(
  name: "callFlutter",
  onMessageReceived: (JavascriptMessage message)    {
     flutterHandle(message)
  }
)
//toFlutterData的定义 
{
   method: string; //需要调用的方法名
   param?: any; //参数需要根据每个需要的方法单独定义
   callbackId: string; //回调的id
}
//js的调用
window['callFlutter'] && window['callFlutter'].postMessage(JSON.stringify(toFlutterData));

这里js的通信需要使用上面定义的callFlutter的postMessage的方式。flutterHandle需要根据method和param去调用对应的方法,结束后就通过主动调用js的方式完成回调。

flutter调用js

通过WebViewController调用evaluateJavascript方法,即可调用JS。evaluateJavascript类似于js中的eval函数,作用就是执行一段js的代码。js可以在bridge初始化的过程中在全局增加一个flutterCallback的函数,该函数的入参可以如下定义

export interface flutterCallbackParam {
  result: number;//状态码标记是否成功
  msg: string;
  callbackId: string; //回调的id
  data?: any;//回调结果
}

当然flutter需要把flutterCallbackParam也转为json,这样整个js调用flutter的过程就可以完成了,而flutter主动调用js的过程就是上面的逆过程。

jsBridge

桥的代码其实大都类似

jsBridge({methodName, params, success, fail}) {
    const callbackID = randomCallbackID(actionID);//生成回调id
    cachedPromise.set(callbackID, { success, fail });//回调池的注册
    const toFlutterData = {
      method:methodName,
      callbackId: callbackID,
      data: params
    });
    window['callFlutter'] && window['callFlutter'].postMessage(JSON.stringify(toFlutterData));
  }
  
 //也可以选择用比较方便的promise的方式
 jsBridgePromise({methodName, params}) {
    const callbackID = randomCallbackID(actionID);
    return new Promise((resolve, reject) => {
      cachedPromise.set(callbackID, { resolve, reject });
      const toFlutterData = ({
        method: methodName,
        callbackId: callbackID,
        data: params
      });
      window['callFlutter'] && window['callFlutter'].postMessage(JSON.stringify(toFlutterData));
    });

之后只要和flutter端约定好methodName和对应的参数格式,在上面的代码之后在包装后的代码就可以暴露给业务使用了。

其他

  • 需要兼容其他环境的bridge,最好的方式就是flutter的桥包装在原有的桥上,然后根据环境判断直接抹平差异,当然这就需要对应的函数和入参的定义接近
  • 需要增加一些兜底判断和错误捕获,保证桥的稳定性
  • 版本控制

总结

目前整个过程还没有实际的做线上实验,所以对于上述的通信效率和问题,还没有一个很好的认识,但基于目前的实现方式,很大程度上会面临和小程序类似的痛点,就是data的数据不能太大,对象转json非常消耗性能,另外就是大量调用的过程中,flutter如何做好批处理的回调也将会是痛点