廖祜秋 · 更新于 2018-11-28 11:00:42

数据源和数据订阅者

本教程内容来源于:http://fresco-cn.org
采用 知识共享 署名 4.0 国际 许可协议 进行许可

数据源Future, 有些相似,都是异步计算的结果。

不同点在于,数据源对于一个调用会返回一系列结果,Future只返回一个。

提交一个Image request之后,Image pipeline返回一个数据源。从中获取数据需要使用数据订阅者(DataSubscriber).

当你仅仅需要Bitmap

如果你请求Image pipeline仅仅是为了获取一个 Bitmap, 对象。你可以利用简单易用的BaseBitmapDataSubscriber:

dataSource.subscribe(new BaseBitmapDataSubscriber() {
    @Override
    public void onNewResultImpl(@Nullable Bitmap bitmap) {
       // You can use the bitmap in only limited ways
      // No need to do any cleanup.
    }

    @Override
    public void onFailureImpl(DataSource dataSource) {
      // No cleanup required here.
    }
  });

看起来很简单,对吧。下面是一些小警告:

千万 不要 把bitmap复制给onNewResultImpl函数范围之外的任何变量。订阅者执行完操作之后,image pipeline 会回收这个bitmap,释放内存。在这个函数范围内再次使用这个Bitmap对象进行绘制将会导致IllegalStateException

通用的解决方案

如果你就是想维持对这个Bitmap对象的引用,你不能维持纯Bitmap对象的引用,可以利用可关闭的引用(closeable references)BaseDataSubscriber:

DataSubscriber dataSubscriber =
    new BaseDataSubscriber<CloseableReference<CloseableImage>>() {
  @Override
  public void onNewResultImpl(
      DataSource<CloseableReference<CloseableImage>> dataSource) {

    if (!dataSource.isFinished()) {
      FLog.v("Not yet finished - this is just another progressive scan.");
    }  

    CloseableReference<CloseableImage> imageReference = dataSource.getResult();
    if (imageReference != null) {
      try {
        CloseableImage image = imageReference.get();
        // do something with the image
      } finally {
        imageReference.close();
      }
    }
  }
  @Override
  public void onFailureImpl(DataSource dataSource) {
    Throwable throwable = dataSource.getFailureCause();
    // handle failure
  }
};

dataSource.subscribe(dataSubscriber, executor);

这样,只要遵守可关闭的引用使用规则,你就可以把这个CloseableReference复制给其他变量了。