使用 BasicMessageChannel 处理 flutte
2021-08-03 本文已影响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
方法中,进行数据处理,发送回值。