概述

#
  • 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

遷移前的程式碼

dart
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);
  }
}

遷移後的程式碼

dart
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