搜索插件、代码仓与 APP 分类

GitHub 代码仓loup-v/streams_channel

streams_channel

对于 Flutter 插件开发:StreamsChannel 受 EventChannel 启发,允许在 Flutter 和平台端之间创建事件流。

streams_channel 项目封面
星标
41
复刻
22
最近推送(UTC)
2022年1月4日
项目状态
未归档

原始 README

以下为英文项目原文快照,最新内容请访问 GitHub。

StreamsChannel for Flutter plugin development

pub package

StreamsChannel is inspired from EventChannel. It allows to create streams of events between Flutter and platform side.

Rationale

EventChannel allows to only create a single open stream per channel. On the first subscription, the stream will be open and it's possible to pass arguments from Flutter to platform side. Subsequent subscriptions will either re-use the open stream or override it with a new one.

In order to have multiple streams open at the same time, with different parameters for stream initialization, one has to create multiple EventChannel. And it gets complicated if the number of streams is dynamic.

Installation

Follow the instructions: https://pub.dev/packages/streams_channel#-installing-tab-

How it works

StreamsChannel works in a similar way than EventChannel. The difference is that it supports multiple open streams at the same time.

On the platform side, the channel takes a stream handler factory:

let channel = FlutterStreamsChannel(name: "my_channel", binaryMessenger: plugin.registrar.messenger())
channel.setStreamHandlerFactory { arguments in
  return MyHandler(arguments) // MyHandler is an instance FlutterStreamHandler
}

On the flutter side, each call to receiveBroadcastStream(args) will create a new stream, that won't replace any previous one that is still running.

  1. The first subscription to the stream will create a new stream handler using the factory on the platform side, then trigger onListen on the handler;
  2. The last subscription to the stream will trigger onCancel on the handler, then destroy the handler instance
  3. If a new first subscription happens afterwards, repeat step 1.

Under the hood, StreamsChannel tracks each stream with a simple auto-incremented unique id.

Example

Flutter side
final StreamsChannel channel = new StreamsChannel('some_channel');

// continuous stream of events from platform side, match some args
channel.receiveBroadcastStream('some args')
  .listen((data) {
    // do something
  });

// another continuous stream of events from platform side, matching some other args
channel.receiveBroadcastStream('some other args')
  .listen((data) {
    // do something
  });
Platform side
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();
      }
    });
  }

  // Send "Hello" 10 times, every second, then ends the stream
  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

// Send "Hello" 10 times, every second, then ends the stream
@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

Author

Beacons plugin is developed by Loup, a mobile development studio based in Montreal and Paris.
You can contact us at <hello@loup.app>

License

Apache License 2.0

Loup GitHub avatar
GitHub 作者

Loup ↗

Montreal & Paris
语言JavaObjective-CRubyDart

分类

此仓库发布的插件

使用的依赖

依赖清单 1 项

  • flutter{"sdk":"flutter"}

如何选择适合项目的代码仓?

先按使用场景筛选,再比较项目活跃情况,最后到原始仓库核对使用要求。

  1. 通过仓库名、作者或描述搜索,再按技术分类缩小范围。
  2. 结合星标、复刻与最近推送比较项目;星标反映社区关注,不代表质量保证。
  3. 使用前在 GitHub 核对 README、许可证与 Issues。

来源与维护

“A repository is the most basic element of GitHub.”

GitHub Docs — About repositories ↗