跳至主要內容

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

遷移前的程式碼

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