在Dart庫中,有兩種實現異步編程的方式(Future和Stream),使用它們只需要在代碼中引入dart:async即可。
Flutter 中,整個 Stream 主要包含了 StreamController、Sink 、Stream 、StreamSubscription 四個對象,通過這四個對象來操控整個Stream的運行。
- StreamController
有一個事件源叫 Stream,為了方便控制 Stream ,官方提供了使用 StreamController 作為管理;同時它對外提供了 StreamSink 對象作為事件輸入口,可通過 sink 屬性訪問; 又提供 stream 屬性提供 Stream 對象的監聽和變換,最后得到的 StreamSubscription 可以管理事件的訂閱。
可以說, StreamController就是如其名字所示一樣用來管理其他三個對象的對象。
- StreamSink
sink英文的意思為水槽,我們可以將其理解為日常生活中的廚房的洗碗槽,洗碗槽(sink)中的水(data)會流進管子(stream)中。一般作為事件的入口,提供如 add , addStream 等。
- StreamSubscription
這是一個事件訂閱后的對象,,Stream中有兩種訂閱模式,分別是單點訂閱和廣播。
表面上用于管理訂閱過等各類操作,如 cacenl 、pause ,同時在內部也是事件的中轉關鍵。
- Stream
事件源本身,一般可用于監聽事件或者對事件進行轉換,如 listen 、 where 。
什么是Stream?
為了將Stream的概念可視化與簡單化,可以將它想成是管道(pipe)的兩端,它只允許從一端插入數據并通過管道從另外一端流出數據。
在Flutter中,
- 我們將這樣的管道稱作Stream;
- 為了控制Stream,我們通常可以使用StreamController來進行管理;
- 為了向Stream中插入數據,StreamController提供了類型為StreamSink的屬性sink作為入口;
- StreamController提供stream屬性作為數據的出口。
class StreamDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('StreamDemo'),
elevation: 0.0,
),
body: StreamTestDemo(),
);
}
}
class StreamTestDemo extends StatefulWidget {
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return StreamTestDemoState();
}
}
class StreamTestDemoState extends State<StreamTestDemo> {
StreamSubscription streamSubscription;
StreamController<String> _streamDemo;
StreamSink _sinkDemo;
var _data = "--";
@override
void initState() {
super.initState();
//使用StreamController 管理Stream
_streamDemo = StreamController<String>();
//為了向Stream中插入數據,StreamController提供了類型為StreamSink的屬性sink作為入口;
_sinkDemo = _streamDemo.sink;
//StreamSubscription 可以管理事件的訂閱 取消 暫停 添加
streamSubscription =
_streamDemo.stream.listen(onData, onError: onError, onDone: onDone);
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
_streamDemo.close();
}
void onData(String data) {
print('---------${data}');
setState(() {
_data = data;
});
}
void onError(error) {
print('--------error:$error');
}
void onDone() {
print('--------Done');
}
Future<String> fetchData() async {
await Future.delayed(new Duration(seconds: 3));
// throw 'soming err';
return 'hello word';
}
void _addDataToStream() async {
print('------Add data to stream.');
String data = await fetchData();
// _streamDemo.add(data);
_sinkDemo.add(data);
}
void _pauseStream() {
print('------Pause subscription');
streamSubscription.pause();
}
void _resumeStream() {
print('------Resume subscription');
streamSubscription.resume();
}
void _cancelStream() {
print('------Cancel subscription');
streamSubscription.cancel();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(_data),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlatButton(
child: Text('Add'),
onPressed: _addDataToStream,
),
FlatButton(
child: Text('Pause'),
onPressed: _pauseStream,
),
FlatButton(
child: Text('Resume'),
onPressed: _resumeStream,
),
FlatButton(
child: Text('Cancel'),
onPressed: _cancelStream,
),
],
),
],
),
),
);
}
}
如下圖 點擊add 后3s后會顯示hello word 同時也可以點擊 暫停 恢復 取消等 查看結果
另外 Stream 還支持多次訂閱
修改代碼
@override
void initState() {
super.initState();
print('-----Create a stream.');
//支持多次訂閱
_streamDemo = StreamController.broadcast();
_sinkDemo = _streamDemo.sink;
print('-----Start listening on a stream.');
_streamDemoSubscription =
_streamDemo.stream.listen(onData, onError: onError, onDone: onDone);
_streamDemo.stream.listen(onDataTwo, onError: onError, onDone: onDone);
print('-----Initialize completed.');
}
void onDataTwo(String data) {
print('-----onDataTwo: $data');
}
運行后便可以查看到兩次的ondata 輸出