Flutter消息编码插件standard_message_codec的使用
Flutter消息编码插件standard_message_codec的使用
standard_message_codec
是Flutter SDK中用于高效编码和解码消息的二进制格式。与基于文本的格式(如JSON)不同,它不需要先解析为字符串再进行结构识别,而是直接操作字节数据,从而提高了效率。此外,它不需要预定义的模式或生成代码,这使得它非常适合动态消息,并且易于集成到现有代码库中。
Features
Efficiency
标准消息编解码是二进制格式,这意味着它避免了像JSON这样的文本格式所需的UTF8解码步骤。例如,考虑以下JSON片段:
{
"data": [1, 2, 3, 4],
}
为了将此消息解码为Dart映射,必须首先将UTF8二进制文件解析并验证为Dart字符串。然后执行第二遍查找表示JSON结构的特定字符(例如"{" 和"}")。在解析过程中,不知道任何大小或长度,因此创建的结果Dart列表是在解码时逐渐追加的。
相比之下,解码标准消息编解码版本的消息避免了UTF8解码,而是直接在字节上操作。唯一构造的字符串将是"data"键。数据字段中的列表长度被编码在结构中,意味着可以分配正确长度的对象并在解码时填充。
Schemaless
使用standard_message_codec
不需要模式(如protobuf)或任何生成的代码。这使得它非常容易用于动态消息,并简化了与现有代码库的集成。但是,这也意味着应用程序有责任验证发送/接收的消息结构。不像protobuf那样自动提供向后兼容性。
Getting Started
standard_message_codec
可以在Flutter或纯Dart应用程序中用于编码和解码消息。下面是一个简单的示例,展示了如何使用它来编码一个消息:
import 'dart:typed_data';
import 'package:flutter/services.dart';
void main() {
// Encoding a message
final ByteData? encodedMessage =
const StandardMessageCodec().encodeMessage(<Object, Object>{
'foo': true,
3: 'fizz',
});
print('The encoded message is $encodedMessage');
// Decoding a message
if (encodedMessage != null) {
final Map<Object?, Object?>? decodedMessage =
const StandardMessageCodec().decodeMessage(encodedMessage);
print('The decoded message is $decodedMessage');
}
}
这段代码首先创建了一个包含两个键值对的消息,然后使用StandardMessageCodec
将其编码为ByteData
对象。之后,它又演示了如何从编码后的ByteData
对象中解码出原始的消息内容。
如果你想要更深入地了解或者查看更多的例子,你可以参考example/README.md,那里提供了更多关于如何在实际项目中使用standard_message_codec
的信息。
更多关于Flutter消息编码插件standard_message_codec的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter消息编码插件standard_message_codec的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,standard_message_codec
是默认的消息编码插件,用于在 Flutter 和原生平台(如 Android 和 iOS)之间传递消息。它支持基本的数据类型,如字符串、数字、布尔值、列表、映射(字典)等。默认情况下,Flutter 的 MethodChannel 和 BasicMessageChannel 已经使用 standard_message_codec
,因此你通常不需要显式地配置它。
以下是一个简单的示例,展示了如何在 Flutter 和原生平台之间使用默认的消息编码(即 standard_message_codec
)传递消息。
Flutter 端代码
首先,创建一个 Flutter 插件通道,用于与原生平台通信。
import 'package:flutter/services.dart';
class MyAppChannel {
static const MethodChannel _channel = MethodChannel('com.example.myapp/channel');
// 从原生平台接收消息
static Future<dynamic> receiveMessage() async {
return _channel.invokeMethod('receiveMessage');
}
// 发送消息到原生平台
static Future<void> sendMessage(String message) async {
try {
await _channel.invokeMethod('sendMessage', {'message': message});
} on PlatformException catch (e) {
print("Failed to send message: '${e.message}'.");
}
}
}
Android 端代码
在 Android 的 MainActivity 中设置 MethodChannel,以响应 Flutter 的消息。
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugin.common.MethodChannel;
import android.os.Bundle;
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "com.example.myapp/channel";
@Override
public void configureFlutterEngine(FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
.setMethodCallHandler(
(call, result) -> {
if (call.method.equals("sendMessage")) {
// 接收来自 Flutter 的消息
String message = call.argument("message");
// 在这里处理消息,比如打印到日志
android.util.Log.d("MyApp", "Received message from Flutter: " + message);
// 发送回复消息给 Flutter
result.success("Message received on Android");
} else if (call.method.equals("receiveMessage")) {
// 发送消息到 Flutter
result.success("Hello from Android");
} else {
result.notImplemented();
}
}
);
}
}
iOS 端代码
在 iOS 的 AppDelegate 中设置 MethodChannel,以响应 Flutter 的消息。
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let channel = FlutterMethodChannel(name: "com.example.myapp/channel", binaryMessenger: controller)
channel.setMethodCallHandler({
(call: FlutterMethodCall, result: @escaping FlutterResult) in
if call.method == "sendMessage" {
if let message = call.arguments as? Dictionary<String, String>, let msg = message["message"] {
// 接收来自 Flutter 的消息
print("Received message from Flutter: \(msg)")
// 发送回复消息给 Flutter
result(success: "Message received on iOS")
} else {
result(FlutterError(code: "INVALID_ARGUMENT", message: "Invalid argument", details: nil))
}
} else if call.method == "receiveMessage" {
// 发送消息到 Flutter
result(success: "Hello from iOS")
} else {
result(FlutterMethodNotImplemented)
}
})
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
使用示例
在 Flutter 端调用这些方法来测试通信:
void _sendMessage() async {
await MyAppChannel.sendMessage("Hello from Flutter");
final result = await MyAppChannel.receiveMessage();
print("Received from native: $result");
}
在 Flutter 的 build
方法中添加一个按钮来触发消息发送:
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Message Codec Example'),
),
body: Center(
child: ElevatedButton(
onPressed: _sendMessage,
child: Text('Send Message'),
),
),
),
);
}
这个示例展示了如何在 Flutter 和原生平台之间使用默认的 standard_message_codec
传递消息。注意,默认情况下,Flutter 的 MethodChannel 已经使用 standard_message_codec
,因此你不需要显式地配置它。