Flutter通讯插件comms的使用
Flutter通讯插件comms的使用
comms
是一个基于流的简单通信模式抽象,旨在简化不同类之间的消息传递。它允许 Listener
类轻松地响应由 Sender
发送的消息。对于Flutter项目,可以使用 flutter_comms。
安装
在终端中运行以下命令来安装 comms
:
dart pub add comms
基本用法
创建 Listener
Listener
是一个mixin,它使你的类能够接收来自任何共享相同消息类型的 Sender
的消息。
class LightBulb with Listener<bool> {
LightBulb() {
listen();
}
bool enabled = false;
@override
void onMessage(bool message) {
enabled = message;
}
void dispose() {
cancel();
}
}
创建 Sender
Sender
mixin用于发送特定类型的消息。
class LightSwitch with Sender<bool> {
void enable() {
send(true);
}
}
使用 Listener 和 Sender
void main() async {
final lightBulb = LightBulb();
final lightSwitch = LightSwitch();
print(lightBulb.enabled); // false
lightSwitch.enable();
await Future<void>.delayed(Duration.zero);
print(lightBulb.enabled); // true
lightBulb.dispose();
}
多个 Listeners 和 Senders
当任何 Sender<A>
发送消息时,所有 Listener<A>
都会收到该消息。
void main() async {
final lightBulbA = LightBulb();
final lightSwitchA = LightSwitch();
final lightBulbB = LightBulb();
final lightSwitchB = LightSwitch();
print(lightBulbA.enabled); // false
print(lightBulbB.enabled); // false
lightSwitchB.enable();
await Future<void>.delayed(Duration.zero);
print(lightBulbA.enabled); // true
print(lightBulbB.enabled); // true
}
处理初始消息
可以通过重写 onInitialMessage
方法来处理创建 Listener
实例之前发送的最后一条消息。
abstract class CounterMessage {}
class CounterIncremented extends CounterMessage {}
class CounterController with Sender<CounterMessage> {
void increment() => send(CounterIncremented());
}
class Counter with Listener<CounterMessage> {
Counter() {
listen();
}
int count = 0;
@override
void onMessage(CounterMessage message) {
if (message is CounterIncremented) {
count++;
}
}
@override
void onInitialMessage(CounterMessage message) => onMessage(message);
}
void main() {
final counterController = CounterController();
counterController.increment();
final counter = Counter();
print(counter.count); // 1
}
监听多种消息类型
如果需要在一个 Listener
类中接收多个消息类型,可以使用 MultiListener
mixin。
class MyListener with MultiListener {
MyListener() {
listen();
}
@override
List<ListenerDelegate> get listenerDelegates => [
ListenerDelegate<CounterMessage>(),
ListenerDelegate<AuthMessage>(),
];
@override
void onMessage(dynamic message) {
if (message is CounterMessage) {...}
if (message is AuthMessage) {...}
}
}
自定义 Sender
可以通过 getSend
函数创建自定义 Sender
来发送多种类型的消息。
mixin CustomSender {
final sendString = getSend<String>();
final sendInt = getSend<int>();
void sendMessages() {
sendString('hello');
sendInt(1);
}
}
也可以直接使用 getSend
函数发送消息而无需创建 Sender
。
void main() {
getSend<bool>()(true);
}
Bloc之间通信
通过使用 Sender
和 Listener
mixins,可以在Bloc之间进行通信。为了更方便,提供了 ListenerCubit
或 ListenerBloc
类和 StateSender
mixin。
创建 ListenerCubit
ListenerCubit
类似于 Listener
,但它自动调用了 listen
和 cancel
函数,使得 Cubit
可以接收来自任何 Sender
的消息。
class LightBulbCubit with ListenerCubit<LightBulbState, LightSwitchState> {
LightBulbCubit() : super(LightBulbState(false));
@override
void onMessage(LightSwitchState message) {
if (message is LightSwitchEnabled) {
emit(LightBulbState(true));
} else if (message is LightSwitchDisabled) {
emit(LightBulbState(false));
}
}
}
class LightBulbState {
LightBulbState(this.enabled);
final bool enabled;
}
创建 StateSender
StateSender
mixin允许你的Bloc在每次发出新状态时发送消息。
class LightSwitchBloc extends Bloc<bool, LightSwitchState>
with StateSender {
LightSwitchBloc() : super(false) {
on<bool>(
(event, emit) {
if (event) {
emit(LightSwitchEnabled());
} else {
emit(LightSwitchDisabled());
}
}
);
}
}
abstract class LightSwitchState {}
class LightSwitchEnabled extends LightSwitchState {}
class LightSwitchDisabled extends LightSwitchState {}
使用 ListenerCubit 和 StateSender
void main() async {
final lightBulbCubit = LightBulbCubit();
final lightSwitchBloc = LightSwitchBloc();
print(lightBulbCubit.state.enabled); // false
lightSwitchBloc.add(true);
await Future<void>.delayed(Duration.zero);
print(lightBulbCubit.state.enabled); // true
lightBulbCubit.close();
lightSwitchBloc.close();
}
实际案例
例如,UserProfileCubit
在用户登录时获取用户资料,在登出时清除数据。
class UserProfileCubit extends ListenerCubit<UserProfileState, AuthState> {
UserProfileCubit({
required UserRepository repository,
}) : _repository = repository,
super(const UserProfileState.initial());
final UserRepository _repository;
@override
void onInitialMessage(AuthState message) => onMessage(message);
@override
void onMessage(AuthState message) {
if (message is AuthStateAuthenticated) {
fetchProfile();
} else {
emit(const UserProfileState.noUser());
}
}
Future<void> fetchProfile() async {...}
}
与传统方法相比,使用 comms
可以减少代码量,并且不需要传递 AuthCubit
的流和初始状态。
希望这些信息能帮助你更好地理解和使用 comms
插件。如果你有任何问题或需要进一步的帮助,请随时提问!
更多关于Flutter通讯插件comms的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter通讯插件comms的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter中使用comms
插件进行通讯的简单代码示例。请注意,comms
并不是一个广泛知名的Flutter插件,所以我将假设它提供了基本的发送和接收消息的功能。如果comms
插件有特定的API或者方法,请参考其官方文档进行调整。
首先,确保你已经在pubspec.yaml
文件中添加了comms
插件的依赖(假设它存在于pub.dev上或者你的私有仓库中):
dependencies:
flutter:
sdk: flutter
comms: ^x.y.z # 替换为实际的版本号
然后运行flutter pub get
来安装依赖。
接下来是一个简单的Flutter应用示例,展示了如何使用comms
插件进行基本的消息发送和接收。
import 'package:flutter/material.dart';
import 'package:comms/comms.dart'; // 假设这是插件的导入路径
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Comms Plugin Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final Comms _comms = Comms(); // 假设Comms有一个默认构造函数
String _receivedMessage = '';
@override
void initState() {
super.initState();
// 监听接收到的消息
_comms.onMessageReceived.listen((String message) {
setState(() {
_receivedMessage = message;
});
});
// 假设有一个初始化连接的方法
_comms.initialize();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Comms Plugin Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Received Message:', style: TextStyle(fontSize: 18)),
SizedBox(height: 8),
Text(_receivedMessage, style: TextStyle(fontSize: 16)),
SizedBox(height: 24),
TextField(
decoration: InputDecoration(labelText: 'Send Message'),
onChanged: (String value) {
// 这里我们假设有一个发送消息的方法
// 实际上应该根据插件的API来调用
_sendMessage(value);
},
),
],
),
),
);
}
void _sendMessage(String message) {
// 发送消息
_comms.sendMessage(message);
// 清空输入框(可选)
// 可以通过TextEditingController来实现更精细的控制
}
@override
void dispose() {
// 取消监听
_comms.onMessageReceived.cancel();
// 假设有一个关闭连接的方法
_comms.close();
super.dispose();
}
}
注意:
- 上面的代码假设
comms
插件有一个initialize
方法来初始化连接,一个sendMessage
方法来发送消息,以及一个onMessageReceived
流来监听接收到的消息。这些假设可能并不准确,因为实际的comms
插件可能有不同的API设计。 - 在真实的应用中,你应该处理更多的错误情况,比如连接失败、消息发送失败等。
- 文本输入框的
onChanged
回调直接调用了_sendMessage
方法,这在真实应用中可能不是最佳实践,因为它会在每次文本变化时都尝试发送消息。更常见的做法是使用一个按钮来触发消息发送。
请根据你实际使用的comms
插件的API文档来调整上述代码。如果comms
插件并不是公开可用的,你可能需要参考其提供的示例代码或文档。