StreamBuilder监听流与常规监听方法的区别

iDe*_*ode 5 dart flutter

我正在使用http库来下载图像。

final client = http.Client();
final _response = await client.send(http.Request('GET', Uri.parse("my_url")));
Run Code Online (Sandbox Code Playgroud)

听音方式一:(听音法)

int downloaded = 0;
_response.stream.listen((value) {
  // this gets called 82 times and I receive actual image size
  downloaded += value.length;
});
Run Code Online (Sandbox Code Playgroud)

监听方式2:(StreamBuilder widget)

int downloaded = 0;
StreamBuilder<List<int>>(
  stream: _response.stream,
  builder: (_, snapshot) {
    // this gets called 11 times and I receive around 1/10 actual image size
    if (snapshot.hasData) downloaded += snapshot.data.length;
    return Container();
  },
);
Run Code Online (Sandbox Code Playgroud)

问题是为什么当新数据到达时StreamBuilder'sbuild()方法没有被频繁调用,它根本就违背了用作小部件的目的。

Alb*_*221 4

StreamBuilder基本上得到了更好的优化,不会在每个新快照上重建。正如StreamBuilder文档所述:

Widget 重建由每次交互使用 State.setState 进行安排,但以其他方式与流的计时分离。构建器由 Flutter 管道自行调用,因此将接收代表与流交互的快照的与时间相关的子序列。

例如,当与生成整数 0 到 9 的流交互时,可以使用以下快照的任何有序子序列来调用构建器,其中包括最后一个快照(带有 ConnectionState.done 的快照):

  • new AsyncSnapshot<int>.withData(ConnectionState.waiting, null)
  • new AsyncSnapshot<int>.withData(ConnectionState.active, 0)
  • new AsyncSnapshot<int>.withData(ConnectionState.active, 1)
  • ...
  • new AsyncSnapshot<int>.withData(ConnectionState.active, 9)
  • new AsyncSnapshot<int>.withData(ConnectionState.done, 9)

构建器的实际调用顺序取决于流生成的事件的相对时间和 Flutter 管道的构建速率。