Flutter通讯插件comms的使用

发布于 1周前 作者 gougou168 来自 Flutter

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之间通信

通过使用 SenderListener mixins,可以在Bloc之间进行通信。为了更方便,提供了 ListenerCubitListenerBloc 类和 StateSender mixin。

创建 ListenerCubit

ListenerCubit 类似于 Listener,但它自动调用了 listencancel 函数,使得 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

1 回复

更多关于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();
  }
}

注意

  1. 上面的代码假设comms插件有一个initialize方法来初始化连接,一个sendMessage方法来发送消息,以及一个onMessageReceived流来监听接收到的消息。这些假设可能并不准确,因为实际的comms插件可能有不同的API设计。
  2. 在真实的应用中,你应该处理更多的错误情况,比如连接失败、消息发送失败等。
  3. 文本输入框的onChanged回调直接调用了_sendMessage方法,这在真实应用中可能不是最佳实践,因为它会在每次文本变化时都尝试发送消息。更常见的做法是使用一个按钮来触发消息发送。

请根据你实际使用的comms插件的API文档来调整上述代码。如果comms插件并不是公开可用的,你可能需要参考其提供的示例代码或文档。

回到顶部