我在颤振中定义了一个 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
。