新增 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