在Android事件总线库中,EventBus库是最普遍之一。 看看Android EventBus库的说明 官网git
咱们要实现一个Flutter版的EventBus!功能以下:github
Demo地址 入口 main_eventbus.dart编程
//发布者接口 abstract class IPublisher { void post<T>(T event); } //订阅者:函数对象 typedef ISubscriber<T> = void Function(T event); //集中式通讯, //1.IEventBus继承IPublisher,分发数据 //2.IEventBus注册和取消注册ISubscriber abstract class IEventBus extends IPublisher { void register<T>(ISubscriber<T> subscriber); void unregister<T>(ISubscriber<T> subscriber); } 复制代码
Type typeOf<T>() => T; class MyEventBus1 implements IEventBus { //咱们用map存放咱们的订阅者。不一样订阅者订阅的Event类型多是不一样的 Map<Type, List<Function>> map = new Map(); @override void register<T>(ISubscriber<T> subscriber) { Type type = typeOf<T>(); if (!map.containsKey(type)) { map[type] = new List(); } map[type].add(subscriber); } @override void unregister<T>(ISubscriber<T> subscriber) { Type type = typeOf<T>(); if (map.containsKey(type)) { map[type].remove(subscriber); } } //发布 @override void post<T>(T event) { Type type = typeOf<T>(); if (map.containsKey(type)) { var subscribers = map[type]; subscribers?.forEach((subscriber) => subscriber?.call(event)); } } } 复制代码
class MyEventBus2 implements IEventBus { List<Function> subscribers = new List(); @override register<T>(ISubscriber<T> subscriber) { if (!subscribers.contains(subscriber)) { subscribers.add(subscriber); } } @override unregister<T>(ISubscriber<T> subscriber) { if (subscribers.contains(subscriber)) { subscribers.remove(subscriber); } } @override post<T>(T event) { var ints = subscribers.whereType<ISubscriber<T>>(); ints?.forEach((subscriber) => subscriber?.call(event)); } } 复制代码
class EventX {} class EventY {} main() { testEventBus(new MyEventBus1()); print("--------------------"); testEventBus(new MyEventBus2()); } void testEventBus(IEventBus eventBus) { ISubscriber<EventX> subscriber1 = (event) => print(event.toString()); ISubscriber<EventX> subscriber2 = (event) => print(event.toString()); eventBus.register(subscriber1); eventBus.register(subscriber2); eventBus.unregister(subscriber1); ISubscriber<EventY> subscriber3 = (event) => print(event.toString()); ISubscriber<EventY> subscriber4 = (event) => print(event.toString()); eventBus.register(subscriber3); eventBus.register(subscriber4); eventBus.post(new EventX()); eventBus.post(new EventY()); } 复制代码
结果输出为如下,测试经过redux
Instance of 'EventX' Instance of 'EventY' Instance of 'EventY' -------------------- Instance of 'EventX' Instance of 'EventY' Instance of 'EventY' 复制代码
点击每行的按钮,每行上的两个数字会增加1 markdown
MyEventBus1 _eventBus = new MyEventBus1(); //首先咱们定义event。第一排用EventA,第二排用EventB class BaseEvent { int count = 0;} class EventA extends BaseEvent {} class EventB extends BaseEvent {} //点击按钮 class ButtonWidget<T extends BaseEvent> extends StatelessWidget { final T event; const ButtonWidget({Key key, this.event}) : super(key: key); @override Widget build(BuildContext context) { return RaisedButton( child: Text("increment"), onPressed: _increment, ); } //点击处理 void _increment() { if (event != null) { event.count++; _eventBus.post(event); } } } //显示数字 class TextWidget<T> extends StatefulWidget { @override _TextWidgetState<T> createState() { return _TextWidgetState<T>(); } } class _TextWidgetState<T> extends State<TextWidget<T>> { int _count = 0; ISubscriber<T> _subscriber; @override void initState() { super.initState(); //经过setState 刷新UI。 _subscriber = (event) => setState(() => _count = (event as BaseEvent).count); //注册 _eventBus.register<T>(_subscriber); } @override Widget build(BuildContext context) { return Text( " $_count ", style: TextStyle(fontSize: 18), ); } @override void dispose() { super.dispose(); //取消注册 _eventBus.unregister<T>(_subscriber); } } //页面主体 class EventBusDemoWidget1 extends StatefulWidget { EventBusDemoWidget1({Key key}) : super(key: key); @override _EventBusDemoWidget1State createState() => _EventBusDemoWidget1State(); } class _EventBusDemoWidget1State extends State<EventBusDemoWidget1> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(eventBusDemo1Title), ), body: Container( child: Column( children: <Widget>[ Row( children: <Widget>[ new ButtonWidget(event: new EventA()), new TextWidget<EventA>(), new TextWidget<EventA>() ], ), Divider( color: Colors.grey, ), Row( children: <Widget>[ new ButtonWidget(event: new EventB()), new TextWidget<EventB>(), new TextWidget<EventB>() ], ) ], ), ), ); } } 复制代码
自定义EventBus大功告成!再来看看别人家的EventBus。app
咱们在pub.dev上找到了一个EventBus库 ,github地址less
An Event Bus using Dart Streams for decoupling applications异步
实际相对于自定义的EventBus,不一样点在ButtonWidget和TextWidget中。async
class ButtonWidget<T extends BaseEvent> extends StatelessWidget { final T event; const ButtonWidget({Key key, this.event}) : super(key: key); @override Widget build(BuildContext context) { return RaisedButton( child: Text("increment"), onPressed: _increment, ); } void _increment() { if (event != null) { event.count++; print(event.count); _eventBus.fire(event); // _eventBus.post(event); } } } class TextWidget<T> extends StatefulWidget { @override _TextWidgetState<T> createState() { return _TextWidgetState<T>(); } } class _TextWidgetState<T> extends State<TextWidget<T>> { int _count = 0; // ISubscriber<T> _subscriber; StreamSubscription<T> _subscriber; @override void initState() { super.initState(); // _subscriber = // (event) => setState(() => _count = (event as BaseEvent).count); // _eventBus.register<T>(_subscriber); _subscriber = _eventBus .on<T>() .listen((event) => setState(() => _count = (event as BaseEvent).count)); } @override Widget build(BuildContext context) { print(typeOf<T>()); return Text( " $_count ", style: TextStyle(fontSize: 18), ); } @override void dispose() { super.dispose(); // _eventBus.unregister<T>(_subscriber); _subscriber.cancel(); } } 复制代码
class EventBus { StreamController _streamController; StreamController get streamController => _streamController; EventBus({bool sync = false}) : _streamController = StreamController.broadcast(sync: sync); EventBus.customController(StreamController controller) : _streamController = controller; Stream<T> on<T>() { if (T == dynamic) { return streamController.stream; } else { return streamController.stream.where((event) => event is T).cast<T>(); } } void fire(event) { streamController.add(event); } void destroy() { _streamController.close(); } } 复制代码
不由感慨,Dart自带Stream,处理异步事件。Stream是Dart:async库的核心API,对异步提供了很是好的支持。 这里简单贴图,体会下Stream。 ide
return streamController.stream.where((event) => event is T).cast<T>(); 复制代码
返回的Stream包了两层 CastStream(_WhereStream(_BroadcastStream),经过这样的处理就能够监听泛型事件了。
_WhereStream先处理
class _WhereStream<T> extends _ForwardingStream<T, T> { final _Predicate<T> _test; _WhereStream(Stream<T> source, bool test(T value)) : _test = test, super(source); //_test即为 (event) => event is T void _handleData(T inputEvent, _EventSink<T> sink) { bool satisfies = _test(inputEvent); if (satisfies) { sink._add(inputEvent); } } } 复制代码
CastStreamSubscription实际作的类型转换
class CastStreamSubscription<S, T> implements StreamSubscription<T> { final StreamSubscription<S> _source; /// User's data handler. May be null. void Function(T) _handleData; CastStreamSubscription(this._source) { _source.onData(_onData); } void _onData(S data) { if (_handleData == null) return; T targetData = data as T; _zone.runUnaryGuarded(_handleData, targetData); } 复制代码
至此,咱们在Provider库StreamProvider中遇到了Stream,咱们在EventBus库中遇到了Stream Dart语言自带优秀的异步编程模型 Stream和Future。 Stream拥有良好的异步模型,滋养了一大波组件库 Provider/BLoC/flutter_redux/Rxdart/fish-redux。 接下来就有必要对Stream进行分析了。