Flutter与Flutter Web的桥接方法

811 阅读1分钟

1. Flutter 端:

注册JavascriptChannel全局对象名,比如叫:nativeBridge

在对应的onMessageReceived中拿到js传过来的数据:JavascriptMessage.message

然后可以根据约定好的格式进行处理即可。

如果需要回传js数据,那可以调用WebviewController.runJavascript进行回调对应的函数即可。

示例代码如下:

 //js function 注册表
get _functions => <String, Function>{"getToken": _getToken};
 //拿token

_getToken(data) async {
  handlerCallback(data);
}

handlerCallback(data) {
  if (data['needCallback']) {
    var args = data['callbackArgs'];
    if (data['needToken']) {
      args = "'${data['callbackArgs']}','true token'";
    }
    doCallback(data['callbackName'], args);
  }
}

doCallback(name, args) {
  _controller.future.then((value) => value.runJavascript("$name($args)"));
}

JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
  return JavascriptChannel(
    name: 'nativeBridge',
    onMessageReceived: (JavascriptMessage msg) async {
      // 将收到的string数据转为json
 Map<String, dynamic> message = json.decode(msg.message);
      final data = await _functions[message["api"]](message["data"]);
    },
  );
}

2. Flutter Web端

写过普通js的都比较了解,与native通信的对象,注册在window对象中。那Flutter里面的怎么注册呢?

  1. 我们需要导入: import 'dart:js' as js;
  2. js的window对象对应到dart里面,就是:js.context对象,我们来看下源码注释就清楚了:
 /// The JavaScript global object, usually `window`.

external JsObject get context;

那如何取对应的对象或函数吗?

  • 对象取法:js.context["nativeBridge"]
  • 函数的取法:js.context.callMethod('postMessage', args)// postMessage是固定的

注:如果是跟native通讯,则args只能传一个值,因为native只接受一个string!

如果需要注册函数,用于native调用,则应该这样写:

js.context["注册函数名"] = 函数;

web端示例代码:

 @override
void initState() {
  js.context["getTokenCallback"] = getTokenCallback;
  super.initState();
}



 // 点击获取Token,完成和flutter项目的交互(调用webview项目方法)
void getToken() {
  js.context["nativeBridge"].callMethod("postMessage", [
    json.encode({
      "api": "getToken",
      "data": {
        "name": 'getToken',
        "needCallback": true,
        "needToken": true,
        "callbackName": 'getTokenCallback',
        "callbackArgs": 'msg'
      },
    }),
  ]);
}

void getTokenCallback(msg, token) {
  showDialog(
      context: context,
      builder: (c) {
        return AlertDialog(
          title: Text('$msg $token'),
        );
      });
}

说了这么多,我们来用图清晰的看一下交互吧:

整体上跟正常js的流程区别不大,只是注册用的window换成了js.context。

参考文章


欢迎加我微信: yk3372 一起交流Flutter问题 ^_^