美文网首页
使用 BasicMessageChannel 处理 flutte

使用 BasicMessageChannel 处理 flutte

作者: 李小轰 | 来源:发表于2021-08-03 15:59 被阅读0次
    引言

    最近碰到个需求,需要在flutter层频繁的调用原生层进行数据转换。我们之前使用 MethodChannel 实现过 flutter 调用原生的能力,但这种方式不适合频次太快的交互场景。

    我们发现 flutter 团队还提供了一种 channel 交互 BasicMessageChannel:

    • 用于传递字符串和半结构化的信息,双向通信,原生可以多次向flutter发送消息
    • 适用于碎片连续性的消息传递
    Flutter层Channel能力封装
    class MessageChannelTool {
      // BasicMessageChannel 的名称要与 native 端相对应
      static const BasicMessageChannel _messageChannel = const BasicMessageChannel('messageChannelPath', StandardMessageCodec());
    
      //提供方法给dart层使用,通过 basicMessageChannel 调用 native 对数据进行中转
      static Future<TransferResult> transformData(TransferParam param) async {
        //我们规范参数类型为 map
        return _messageChannel
            .send(param.toJson())
            .then((value) => TransferResult.fromNative(value));
      }
    }
    
    // 我们规定的传参模型范式
    class TransferParam {
      final String name;
      final int age;
    
      TransferParam(this.name, this.age);
    
      HashMap<String, dynamic> toJson() {
        return new HashMap<String, dynamic>()
          ..['name'] = name
          ..['age'] = age;
      }
    }
    
    // 我们规定的回参模型范式
    class TransferResult {
      final int code;
      final String data;
    
      TransferResult({this.code, this.data});
    
      factory TransferResult.fromNative(dynamic result) {
        return TransferResult(
          code: result['code'],
          data: result['data'],
        );
      }
    }
    
    • MessageChannelTool : 定义channel名称,封装提供方法给dart层调用native

    我们规范channel通信以 map 结构进行传参和回值,根据业务需要各自定义的 map 模型。

    • TransferParam:传参模型
    • TransferResult:回值模型
    使用方式
    TransferResult result = await MessageChannelTool.transformData(TransferParam("rex", 18));
    

    完整的UI调用代码:

    class _MyAppState extends State<MyApp> {
      String _data = "";
    
      //发送数据到原生进行封装
      _onTrasformData() async {
        TransferResult result = await MessageChannelTool.transformData(TransferParam("rex", 18));
        setState(() {
          _data = "${result.code}, ${result.data}";
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Container(
                width: 30,
                height: 30,
                child: CircularProgressIndicator(),
              ),
              TextButton(
                  onPressed: () {
                    _onTrasformData();
                  },
                  child: Text("发送数据到原生")),
              Text('原生返回数据:$_data'),
            ],
          ),
        );
      }
    }
    
    原生层Channel能力封装
    class TestBasicMessageChannelPlugin : FlutterPlugin,
        BasicMessageChannel.MessageHandler<Any> {
    
        companion object {
            //注意,名字要与flutter层一一对应
            const val MESSAGE_CHANNEL_PATH = "messageChannelPath"
        }
    
        private lateinit var messageChannel: BasicMessageChannel<Any>
    
        override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
            messageChannel = BasicMessageChannel(
                flutterPluginBinding.binaryMessenger,
                MESSAGE_CHANNEL_PATH,
                StandardMessageCodec()
            )
            messageChannel.setMessageHandler(this)
        }
    
        override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
            //暂无处理
        }
    
        override fun onMessage(
            message: Any?,
            reply: BasicMessageChannel.Reply<Any>
        ) {
            message?.let {
                //接收参数
                val mapParams = it as Map<String, Any>;
                val name = mapParams["name"]
                val age = mapParams["age"]
                //发送回值
                reply.reply(createResult(1, "hello, $name is $age"))
            }
        }
    
        private fun createResult(code: Int, data: String): HashMap<String, Any> {
            var result = HashMap<String, Any>()
            result["code"] = code
            result["data"] = data
            return result
        }
    }
    

    注解很详细,在 onMessage 方法中,进行数据处理,发送回值。

    相关文章

      网友评论

          本文标题:使用 BasicMessageChannel 处理 flutte

          本文链接:https://www.haomeiwen.com/subject/qsrevltx.html