注册

Flutter开发·Stream的理解与简单使用

介绍


Stream和Future都是在Flutter中常用来处理异步事件的对象,与Future只能处理单次异步操作不同的是,Stream具有多次响应异步事件监听的功能,是一系列异步事件的序列。


分类


Stream从订阅模式上分可以分为两类,一个是单订阅模式,另一个是多订阅模式,也称广播模式,单订阅模式表示只能有1个监听器对事件进行监听,即使前面的监听器取消了监听,也无法继续对这个stream进行二次监听,而多订阅模式则可以有多个监听器。


组成


Stream中主要包含了四个对象:



  • Stream:事件源,一般用于事件监听或事件转换等。
  • StreamController: 方便进行Stream管理的控制器。
  • StreamSink: 事件的输入口,包含add等方法进行事件发送。
  • StreamSubscription: Stream进行listen监听后得到的对象,用来管理事件订阅,包含取消监听等方法。

写法


单订阅模式


直接使用StreamController<int>()进行初始化,然后获取到stream对象进行listen监听。当点击按钮时通过获取sink对象,调用add方法进行事件发送,这样listen方法中就可以监听到事件响应。


StreamController<int> singleStreamController = StreamController<int>();

int num = 0;

@override
void initState() {
// TODO: implement initState
super.initState();
singleStreamController.stream.listen((event) {
setState(() {
num = event;
});
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: [
Text("the num is $num"),
FlatButton(onPressed: (){
singleStreamController.sink.add(1);
}, child: Text("点击"))
],
),
);
}

在上面的代码中,如果我在点击按钮时再开启一个监听的话,则会报如下错误,这就是单订阅模式的限制。


image.png


多订阅模式(广播模式)


正如广播这个名字一样,Stream也提供了broadcast方法生成可以注册多个监听器的stream。只需要将上面的初始化代码替换成这句话即可。


StreamController<int> singleStreamController = StreamController<int>.broadcast();

当我多次进行stream事件监听时,程序没有出现出任何的错误,这就是多订阅模式。


image.png


注意,在不再使用stream事件监听时要及时调用close和cancel方法进行取消订阅和事件流关闭。


StreamBuilder


上面的例子是点击界面中的按钮改变数值,通过sink发送事件,然后stream监听到数值变化再进行setState进行状态改变。其实流程还是有点绕的,Stream中也提供了可以直接在控件中获取Stream监听的写法就是StreamBuilder。如上面的代码可以写成:


StreamController<int> singleStreamController = StreamController<int>.broadcast();

@override
void initState() {
// TODO: implement initState
super.initState();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: [
StreamBuilder<Object>(
stream: singleStreamController.stream,
builder: (context, snapshot) {
return Text("the num is ${snapshot.data}");
}
),
FlatButton(onPressed: (){
singleStreamController.sink.add(1);
}, child: Text("点击"))
],
),
);
}

其中,stream参数就是需要进行监听的数据对应的事件流对象,initialData参数是指定当stream还没有存储过数据时的默认值。builder方法中返回需要构建的控件,其中的snapshot参数为数据快照,它的data就是所存储的数据。
这样就可以在控件中监听到数据的变化,无需再调用setState方法。通过指定StreamBuilder中的stream对象,从而实现数据与界面的绑定。


作者:单总不会亏待你
链接:https://juejin.cn/post/7018189703102857246
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册