添加 ImageProvider.loadBuffer
概述
#ImageProvider现在有一个名为loadBuffer的方法,其功能与load类似,但它从ui.ImmutableBuffer解码。ui.ImmutableBuffer现在可以直接从资源键创建。AssetBundle类现在可以加载ui.ImmutableBuffer。PaintingBinding现在有一个名为instantiateImageCodecFromBuffer的方法,其功能与instantiateImageCodec类似。ImageProvider.load现在已弃用,将在未来的版本中移除。PaintingBinding.instantiateImageCodec现在已弃用,将在未来的版本中移除。
背景
#ImageProvider.loadBuffer 是一个新方法,必须实现该方法才能加载图像。此 API 允许以更快的速度加载基于资源的图像,并减少应用程序的内存占用。
变更说明
#在加载资源图像时,以前的图像提供程序 API 需要多份压缩数据的副本。首先,在打开资源时,数据会被复制到外部堆并以类型化数据数组的形式暴露给 Dart。然后,该类型化数据数组最终会被转换为 ui.ImmutableBuffer,该对象在内部将数据复制到第二个结构中以进行解码。
通过添加 ui.ImmutableBuffer.fromAsset,可以将压缩图像字节直接加载到用于解码的结构中。使用此方法需要更改 ImageProvider 的字节加载管道。此过程也更快,因为它绕过了之前基于方法通道的加载器的一些额外的调度开销。
ImageProvider.loadBuffer 的其他方面与 ImageProvider.load 的契约相同,但它提供了一个新的解码回调,该回调期望一个 ui.ImmutableBuffer 而不是 Uint8List。对于从资源以外的地方获取字节的 ImageProvider 类,可以使用便利方法 ui.ImmutableBuffer.fromUint8List 来实现兼容性。
迁移指南
#继承 ImageProvider 的类必须实现 loadBuffer 方法来加载资源。直接委托给或调用 ImageProvider 方法的类必须使用 loadBuffer 而不是 load。
迁移前的代码
class MyImageProvider extends ImageProvider<MyImageProvider> {
@override
ImageStreamCompleter load(MyImageProvider key, DecoderCallback decode) {
return MultiFrameImageStreamCompleter(
codec: _loadData(key, decode),
);
}
Future<ui.Codec> _loadData(MyImageProvider key, DecoderCallback decode) async {
final Uint8List bytes = await bytesFromSomeApi();
return decode(bytes);
}
}
class MyDelegatingProvider extends ImageProvider<MyDelegatingProvider> {
MyDelegatingProvider(this.provider);
final ImageProvder provider;
@override
ImageStreamCompleter load(MyDelegatingProvider key, DecoderCallback decode) {
return provider.load(key, decode);
}
}迁移后的代码
class MyImageProvider extends ImageProvider<MyImageProvider> {
@override
ImageStreamCompleter loadBuffer(MyImageProvider key, DecoderBufferCallback decode) {
return MultiFrameImageStreamCompleter(
codec: _loadData(key, decode),
);
}
Future<ui.Codec> _loadData(MyImageProvider key, DecoderBufferCallback decode) async {
final Uint8List bytes = await bytesFromSomeApi();
final ui.ImmutableBuffer buffer = await ui.ImmutableBuffer.fromUint8List(bytes);
return decode(buffer);
}
}
class MyDelegatingProvider extends ImageProvider<MyDelegatingProvider> {
MyDelegatingProvider(this.provider);
final ImageProvder provider;
@override
ImageStreamCompleter loadBuffer(MyDelegatingProvider key, DecoderCallback decode) {
return provider.loadBuffer(key, decode);
}
}在这两种情况下,您都可以选择保留 ImageProvider.load 的先前实现,以便您的代码用户也能有时间进行迁移。
时间线
#已登陆版本:3.1.0-0.0.pre.976
稳定版发布:3.3.0
参考资料
#API 文档
相关 PR