Flutter数据流通信插件streams_channel2的使用

Flutter数据流通信插件streams_channel2的使用

StreamsChannel for Flutter plugin development

StreamsChannel 是受 EventChannel 启发而开发的,它允许在 Flutter 和平台端之间创建事件流。


Rationale

EventChannel 只能为每个通道创建一个打开的流。首次订阅时,流会被打开,并且可以从 Flutter 端传递参数到平台端。后续的订阅要么重用现有的打开流,要么用新的流覆盖旧的流。

为了在同一时间支持多个打开的流,并为流初始化提供不同的参数,需要创建多个 EventChannel。如果流的数量是动态的,这会变得复杂。


Installation

请按照以下说明进行安装:
https://pub.dev/packages/streams_channel#-installing-tab-


How it works

StreamsChannel 的工作方式与 EventChannel 类似,但它的特点是能够同时支持多个打开的流。

平台端

在平台端,通道接受一个流处理器工厂:

let channel = FlutterStreamsChannel(name: "my_channel", binaryMessenger: plugin.registrar.messenger())
channel.setStreamHandlerFactory { arguments in
  return MyHandler(arguments) // MyHandler 是一个 FlutterStreamHandler 实例
}

Flutter 端

在 Flutter 端,每次调用 receiveBroadcastStream(args) 都会创建一个新的流,不会替换任何仍在运行的旧流。

  1. 第一次订阅流时,会在平台端使用工厂创建一个新的流处理器,然后触发处理器的 onListen 方法;
  2. 最后一次取消订阅时,触发处理器的 onCancel 方法,然后销毁处理器实例;
  3. 如果之后有新的第一次订阅,重复步骤 1。

底层实现中,StreamsChannel 使用简单的自增唯一 ID 来跟踪每个流。


Example

Flutter 端

final StreamsChannel streamsChannel = StreamsChannel('streams_channel_example');

// 持续从平台端接收带有某些参数的事件流
streamsChannel.receiveBroadcastStream('Stream A')
  .listen((data) {
    debugPrint('Received from Stream A: $data');
  });

// 另一个持续从平台端接收带有其他参数的事件流
streamsChannel.receiveBroadcastStream('Stream B')
  .listen((data) {
    debugPrint('Received from Stream B: $data');
  });

平台端

Android
public class DemoPlugin {
  public static void registerWith(PluginRegistry.Registrar registrar) {
    final StreamsChannel channel = new StreamsChannel(registrar.messenger(), "streams_channel_test");
    channel.setStreamHandlerFactory(new StreamsChannel.StreamHandlerFactory() {
      @Override
      public EventChannel.StreamHandler create(Object arguments) {
        return new StreamHandler();
      }
    });
  }

  // 每秒发送 "Hello" 10次,然后结束流
  public static class StreamHandler implements EventChannel.StreamHandler {

    private final Handler handler = new Handler();
    private final Runnable runnable = new Runnable() {
      @Override
      public void run() {
        if (count > 10) {
            eventSink.endOfStream();
        } else {
            eventSink.success("Hello " + count + "/10");
        }
        count++;
        handler.postDelayed(this, 1000);
      }
    };

    private EventChannel.EventSink eventSink;
    private int count = 1;

    @Override
    public void onListen(Object o, final EventChannel.EventSink eventSink) {
      this.eventSink = eventSink;
      runnable.run();
    }

    @Override
    public void onCancel(Object o) {
      handler.removeCallbacks(runnable);
    }
  }
}
iOS
@interface StreamHandler : NSObject<FlutterStreamHandler>
@property(strong, nonatomic) NSTimer *timer;
@property(assign, nonatomic) NSInteger count;
@end

@implementation DemoPlugin

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
  FlutterStreamsChannel *channel = [FlutterStreamsChannel streamsChannelWithName:@"streams_channel_test" binaryMessenger:registrar.messenger];
  [channel setStreamHandlerFactory:^NSObject<FlutterStreamHandler> *(id arguments) {
    return [StreamHandler new];
  }];
}

@end

// 每秒发送 "Hello" 10次,然后结束流
@implementation StreamHandler

- (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events {
  self.count = 1;
  self.timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
    if(self.count > 10) {
      events(FlutterEndOfEventStream);
    } else {
      events([NSString stringWithFormat:@"Hello %ld/10", (long)self.count]);
      self.count++;
    }
  }];

  return nil;
}

- (FlutterError *)onCancelWithArguments:(id)arguments {
  [self.timer invalidate];
  self.timer = nil;
  return nil;
}
@end

完整示例

Flutter 端代码 (main.dart)

// Copyright (c) 2021 Kfir Matityahu
// Licensed under Apache License v2.0

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:streams_channel2/streams_channel2.dart';

void main() => runApp(MyApp());

final StreamsChannel streamsChannel = StreamsChannel('streams_channel_example');

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  StreamSubscription<dynamic>? _subscriptionA;
  StreamSubscription<dynamic>? _subscriptionB;

  void _start(bool a) {
    // 取消当前订阅
    StreamSubscription<dynamic>? subscription = a ? _subscriptionA : _subscriptionB;

    if (subscription != null) {
      subscription.cancel();
      subscription = null;
    } else {
      // 创建新订阅
      final streamId = 'Stream ${a ? 'A' : 'B'}';
      subscription = streamsChannel
          .receiveBroadcastStream(streamId)
          .listen((data) => debugPrint('Received from $streamId: $data'));

      subscription.onDone(() {
        setState(() {
          if (a) {
            _subscriptionA = null;
          } else {
            _subscriptionB = null;
          }
        });
      });
    }

    setState(() {
      if (a) {
        _subscriptionA = subscription;
      } else {
        _subscriptionB = subscription;
      }
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Demo'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              FlatButton(
                onPressed: () => _start(true),
                child: Text(_subscriptionA != null ? 'Stop A' : 'Start A'),
              ),
              FlatButton(
                onPressed: () => _start(false),
                child: Text(_subscriptionB != null ? 'Stop B' : 'Start B'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
1 回复

更多关于Flutter数据流通信插件streams_channel2的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


streams_channel2 是一个用于在 Flutter 和原生平台(如 Android 和 iOS)之间进行数据流通信的插件。它允许你在 Flutter 和原生代码之间建立双向的数据流,从而实现高效的数据传输和通信。

安装

首先,你需要在 pubspec.yaml 文件中添加 streams_channel2 依赖:

dependencies:
  streams_channel2: ^1.0.0

然后运行 flutter pub get 来安装依赖。

基本用法

streams_channel2 提供了 StreamsChannel 类,用于在 Flutter 和原生平台之间建立数据流通信。你可以通过它来发送和接收数据。

1. 在 Flutter 中创建 StreamsChannel

import 'package:streams_channel2/streams_channel2.dart';

final streamsChannel = StreamsChannel('com.example.my_channel');

2. 发送数据到原生平台

streamsChannel.send('Hello from Flutter!');

3. 接收来自原生平台的数据

streamsChannel.receiveBroadcastStream().listen((data) {
  print('Received from native: $data');
});

在原生平台中实现

你需要在原生平台(Android 和 iOS)中实现相应的逻辑来处理 Flutter 发送的数据,并向 Flutter 发送数据。

Android 实现

MainActivity.kt 中:

import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.MethodChannel

class MainActivity: FlutterActivity() {
    private val CHANNEL = "com.example.my_channel"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        val eventChannel = EventChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
        eventChannel.setStreamHandler(object : EventChannel.StreamHandler {
            override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
                // 处理 Flutter 发送的数据
                events?.success("Hello from Android!")
            }

            override fun onCancel(arguments: Any?) {
                // 取消监听
            }
        })
    }
}

iOS 实现

AppDelegate.swift 中:

import UIKit
import Flutter

[@UIApplicationMain](/user/UIApplicationMain)
[@objc](/user/objc) class AppDelegate: FlutterAppDelegate {
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        let controller = window?.rootViewController as! FlutterViewController
        let eventChannel = FlutterEventChannel(name: "com.example.my_channel", binaryMessenger: controller.binaryMessenger)
        eventChannel.setStreamHandler(self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
}

extension AppDelegate: FlutterStreamHandler {
    public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
        // 处理 Flutter 发送的数据
        events("Hello from iOS!")
        return nil
    }

    public func onCancel(withArguments arguments: Any?) -> FlutterError? {
        // 取消监听
        return nil
    }
}
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!