为什么在颤动中加载 gif 时 ImageStreamListener 不会停止

时间:2021-07-31 02:43:10

标签: flutter

我在颤振中定义了一个 ImageStreamListener

ImageStreamListener listener =
        ImageStreamListener((ImageInfo image, bool synchronousCall) {
      var myImage = image.image;
      Size size = Size(myImage.width.toDouble(), myImage.height.toDouble());
      if (!completer.isCompleted) {
        completer.complete(size);
      }
    }, onError: (object, stacktrace) {
      if (!completer.isCompleted) {
        completer.completeError(object);
      }
    });
image.image.resolve(ImageConfiguration()).addListener(listener);

但我发现当 Image.Network 加载 gif 图像时,即使退出 gif 显示页面,ImageStreamListener 也不会停止接收图像通知信息。 gif 图像(https://tva1.sinaimg.cn/mw690/006v119zly1gsu8ni6jbbg30a007q1l2.gif)循环播放是否会自动导致问题? gif 将逐帧播放并通知 ImageStreamListener。使用循环gif,此操作可能会导致永远渲染,并且应用程序运行卡住,我应该怎么做才能避免这种死渲染循环?这是我的完整代码:

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_hooks/flutter_hooks.dart';

class LearnApp extends HookWidget {
  var gifUrl =
      "https://tva1.sinaimg.cn/mw690/006v119zly1gsu8ni6jbbg30a007q1l2.gif";

  Widget load() {
    Completer<Size> completer = Completer();
    Image image = Image.network(gifUrl, frameBuilder: (ctx, child, frame, _) {
      if (frame == null) {
        if (!completer.isCompleted) {
          completer.completeError("error");
        }
        return child;
      } else {
        return child;
      }
    });

    ImageStreamListener listener =
        ImageStreamListener((ImageInfo image, bool synchronousCall) {
      var myImage = image.image;
      Size size = Size(myImage.width.toDouble(), myImage.height.toDouble());
      // debug here you can find the stream forever
      print(image.debugLabel);
      if (!completer.isCompleted) {
        completer.complete(size);
      }
    }, onError: (object, stacktrace) {
      if (!completer.isCompleted) {
        completer.completeError(object);
      }
    });

    image.image.resolve(ImageConfiguration()).addListener(listener);

    var fb = FutureBuilder<Size>(
      future: completer.future,
      builder: (BuildContext buildContext, AsyncSnapshot<Size> snapshot) {
        if (snapshot.hasData) {
          return Image.network(
            gifUrl,
            frameBuilder: (ctx, child, frame, _) {
              if (frame == null) {
                return Text("dd");
              }
              return child;
            },
          );
        } else if (snapshot.hasError) {
          return Text("error");
        } else {
          return Text("dd");
        }
      },
    );

    if (completer.isCompleted) {
      image.image.resolve(ImageConfiguration()).removeListener(listener);
    }

    return fb;
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text("widget title"),
      ),
      body: SafeArea(child: load()),
    );
  }
}

我尝试跟踪代码,发现当我使用此代码添加一个ImageStreamListener时,它之前添加了另一个ImageStreamListener,然后添加了由我的代码创建的ImageStreamListener。为什么要添加另一个ImageStreamListener?另一个 ImageStreamListener 来自哪里?

...我知道其中一个来自MultiFrameImageStreamCompleter

0 个答案:

没有答案