Fresco解析

来源:互联网 发布:vb cmd命令 进入某目录 编辑:程序博客网 时间:2024/06/05 19:01

Fresco解析

1.Fresco初始化

1.Fresco调用时必须先调用Fresco.initialize(Context) (ImagePipelineFactory.java)

private static PipelineDraweeControllerBuilderSupplier sDraweeControllerBuilderSupplier;/** Initializes Fresco with the default config. */public static void initialize(Context context) {  ImagePipelineFactory.initialize(context);  initializeDrawee(context);}private static void initializeDrawee(Context context) {  sDraweeControllerBuilderSupplier = new PipelineDraweeControllerBuilderSupplier(context);  SimpleDraweeView.initialize(sDraweeControllerBuilderSupplier);}

initilize方法做了两件事 :
1. 使用ImagePipelineConfig创建ImagePipelineFactory, factory可以使用config创建出ImagePipeline.

ImagePipline是什么?官方文档是这么说的:
Image pipeline 负责完成加载图像,变成Android设备可呈现的形式所要做的每个事情。

大致流程如下:

  • 检查内存缓存,如有,返回
  • 后台线程开始后续工作
  • 检查是否在未解码内存缓存中。如有,解码,变换,返回,然后缓存到内存缓存中。
  • 检查是否在文件缓存中,如果有,变换,返回。缓存到未解码缓存和内存缓存中。
  • 从网络或者本地加载。加载完成后,解码,变换,返回。存到各个缓存中。

既然本身就是一个图片加载组件,那么一图胜千言。
enter image description here

上图中,disk cache实际包含了未解码的内存缓存在内,统一在一起只是为了逻辑稍微清楚一些。关于缓存,更多细节可以参考这里。

Image pipeline 可以从本地文件加载文件,也可以从网络。支持PNG,GIF,WebP, JPEG。

  1. sDraweeControllerBuilderSupplier 传给SimpleDraweeView,SimpleDraweeView 使用setImageURI加载图片时,前者会生成DraweeController实现具体的加载流程。

1.ImagePipelineFactory.initialize(context)

先看一下ImagePipelineFactory的initialize方法:(ImagePipelineFactory.java)

private static ImagePipelineFactory sInstance = null;private final ThreadHandoffProducerQueue mThreadHandoffProducerQueue;/** Gets the instance of {@link ImagePipelineFactory}. */public static ImagePipelineFactory getInstance() {  return Preconditions.checkNotNull(sInstance, "ImagePipelineFactory was not initialized!");}/** Initializes {@link ImagePipelineFactory} with default config. */public static void initialize(Context context) {  initialize(ImagePipelineConfig.newBuilder(context).build());}/** Initializes {@link ImagePipelineFactory} with the specified config. */public static void initialize(ImagePipelineConfig imagePipelineConfig) {  sInstance = new ImagePipelineFactory(imagePipelineConfig);}

ImagePipelineConfig使用的Builder模式,AlertDialog使用的也是类似的模式 (ImagePipelineConfig.java)

/** * Master configuration class for the image pipeline library. * * To use: * <code> *   ImagePipelineConfig config = ImagePipelineConfig.newBuilder() *       .setXXX(xxx) *       .setYYY(yyy) *       .build(); *   ImagePipelineFactory factory = new ImagePipelineFactory(config); *   ImagePipeline pipeline = factory.getImagePipeline(); * </code> * * <p>This should only be done once per process. */public class ImagePipelineConfig {// There are a lot of parameters in this class. Please follow strict alphabetical order.@Nullable private final AnimatedImageFactory mAnimatedImageFactory;private final Bitmap.Config mBitmapConfig;private final Supplier<MemoryCacheParams> mBitmapMemoryCacheParamsSupplier;。。。。。。private ImagePipelineConfig(Builder builder) {  mAnimatedImageFactory = builder.mAnimatedImageFactory;  mBitmapMemoryCacheParamsSupplier =      builder.mBitmapMemoryCacheParamsSupplier == null ?          new DefaultBitmapMemoryCacheParamsSupplier(              (ActivityManager) builder.mContext.getSystemService(Context.ACTIVITY_SERVICE)) :          builder.mBitmapMemoryCacheParamsSupplier;  mBitmapConfig =      builder.mBitmapConfig == null ?          Bitmap.Config.ARGB_8888 :          builder.mBitmapConfig;。。。。。。}//调用的唯一入口(Builder的构造方法是private的)public static Builder newBuilder(Context context) {  return new Builder(context);}public static class Builder {  private AnimatedImageFactory mAnimatedImageFactory;  private Bitmap.Config mBitmapConfig;  private Supplier<MemoryCacheParams> mBitmapMemoryCacheParamsSupplier;  。。。  。。。private Builder(Context context) {  // Doesn't use a setter as always required.  mContext = Preconditions.checkNotNull(context);}public Builder setAnimatedImageFactory(AnimatedImageFactory animatedImageFactory) {  mAnimatedImageFactory = animatedImageFactory;  return this;}public Builder setBitmapsConfig(Bitmap.Config config) {  mBitmapConfig = config;  return this;}//生成ImagePipelineConfigpublic ImagePipelineConfig build() {  return new ImagePipelineConfig(this);}}}

ImagePipelineFactory用于创建ImagePipeline,文档里强烈推荐把ImagePipelineFactory和ImagePipeline都作为单例实现:(ImagePipelineFactory.java)

/*** Factory class for the image pipeline.** <p>This class constructs the pipeline and its dependencies from other libraries.** <p>As the pipeline object can be quite expensive to create, it is strongly* recommended that applications create just one instance of this class* and of the pipeline.*/@NotThreadSafepublic class ImagePipelineFactory {  private static ImagePipelineFactory sInstance = null;  /** Gets the instance of {@link ImagePipelineFactory}. */  public static ImagePipelineFactory getInstance() {    return Preconditions.checkNotNull(sInstance, "ImagePipelineFactory was not initialized!");  }   。。。。public ImagePipeline getImagePipeline() {  if (mImagePipeline == null) {    mImagePipeline =        new ImagePipeline(            getProducerSequenceFactory(),            mConfig.getRequestListeners(),            mConfig.getIsPrefetchEnabledSupplier(),            getBitmapMemoryCache(),            getEncodedMemoryCache(),            getMainBufferedDiskCache(),            getSmallImageBufferedDiskCache(),            mConfig.getCacheKeyFactory(),            mThreadHandoffProducerQueue);  }  return mImagePipeline;}

2.initializeDrawee(context)

再看一下initialize的第二步 initializeDrawee(context);
Fresco的initializeDrawee(context)方法: (Fresco.java)

private static PipelineDraweeControllerBuilderSupplier sDraweeControllerBuilderSupplier;private static void initializeDrawee(Context context) {  sDraweeControllerBuilderSupplier = new PipelineDraweeControllerBuilderSupplier(context);  SimpleDraweeView.initialize(sDraweeControllerBuilderSupplier);}

PipelineDraweeControllerBuilderSupplier也是作为一个单例存在。

1.PipelineDraweeControllerBuilderSupplier 构造方法

public class PipelineDraweeControllerBuilderSupplier implements Supplier<PipelineDraweeControllerBuilder>{public PipelineDraweeControllerBuilderSupplier(Context context) {  this(context, ImagePipelineFactory.getInstance());}。。。}

PipelineDraweeControllerBuilderSupplier 实现了Supplier接口,Supplier引用于Google Guava项目(https://github.com/google/guava)

/** * A class that can supply objects of a single type.  Semantically, this could * be a factory, generator, builder, closure, or something else entirely. No * guarantees are implied by this interface. * * @author Harry Heymann * @since 2.0 (imported from Google Collections Library) */public interface Supplier<T> {  /**   * Retrieves an instance of the appropriate type. The returned object may or   * may not be a new instance, depending on the implementation.   *   * @return an instance of the appropriate type   */  T get();}

PipelineDraweeControllerBuilderSupplier 的构造方法如下:(PipelineDraweeControllerBuilderSupplier.java)

private final Context mContext;private final ImagePipeline mImagePipeline;private final PipelineDraweeControllerFactory mPipelineDraweeControllerFactory;private final Set<ControllerListener> mBoundControllerListeners;public PipelineDraweeControllerBuilderSupplier(Context context) {  this(context, ImagePipelineFactory.getInstance());}public PipelineDraweeControllerBuilderSupplier(    Context context,    ImagePipelineFactory imagePipelineFactory) {  this(context, imagePipelineFactory, null);}public PipelineDraweeControllerBuilderSupplier(    Context context,    ImagePipelineFactory imagePipelineFactory,    Set<ControllerListener> boundControllerListeners) {  mContext = context;  mImagePipeline = imagePipelineFactory.getImagePipeline();  mPipelineDraweeControllerFactory = new PipelineDraweeControllerFactory(      context.getResources(),      DeferredReleaser.getInstance(),      imagePipelineFactory.getAnimatedDrawableFactory(),      UiThreadImmediateExecutorService.getInstance());  mBoundControllerListeners = boundControllerListeners;}

这里也通过ImagePipelineFactory.getImagePipeline创建了ImagePipeline,

PipelineDraweeControllerFactory是一个工厂类,用于创建PipelineDraweeController,DraweeController用于处理图片加载的逻辑,后面再说。

2.SimpleDraweeView.initialize(sDraweeControllerBuilderSupplier)

SimpleDraweeView.initialize(sDraweeControllerBuilderSupplier) (SimpleDraweeView.java)

/*** This view takes a uri as input and internally builds and sets a controller.** <p>This class must be statically initialized in order to be used. If you are using the Fresco* image pipeline, use {@link com.facebook.drawee.backends.pipeline.Fresco#initialize} to do this.*/public class SimpleDraweeView extends GenericDraweeView {  private static Supplier<? extends SimpleDraweeControllerBuilder> sDraweeControllerBuilderSupplier;  /** Initializes {@link SimpleDraweeView} with supplier of Drawee controller builders. */  public static void initialize(      Supplier<? extends SimpleDraweeControllerBuilder> draweeControllerBuilderSupplier) {    sDraweeControllerBuilderSupplier = draweeControllerBuilderSupplier;  }  /** Shuts {@link SimpleDraweeView} down. */  public static void shutDown() {    sDraweeControllerBuilderSupplier = null;  }  private SimpleDraweeControllerBuilder mSimpleDraweeControllerBuilder;  public SimpleDraweeView(Context context, GenericDraweeHierarchy hierarchy) {    super(context, hierarchy);    init();  }  public SimpleDraweeView(Context context) {    super(context);    init();  }  public SimpleDraweeView(Context context, AttributeSet attrs) {    super(context, attrs);    init();  }  …..  private void init() {    if (isInEditMode()) {      return;    }    Preconditions.checkNotNull(        sDraweeControllerBuilderSupplier,        "SimpleDraweeView was not initialized!");    mSimpleDraweeControllerBuilder = sDraweeControllerBuilderSupplier.get();  }  protected SimpleDraweeControllerBuilder getControllerBuilder() {    return mSimpleDraweeControllerBuilder;  }  /**  * Displays an image given by the uri.  *  * @param uri uri of the image  * @undeprecate  */  @Override  public void setImageURI(Uri uri) {    setImageURI(uri, null);  }  /**  * Displays an image given by the uri.  *  * @param uri uri of the image  * @param callerContext caller context  */  public void setImageURI(Uri uri, @Nullable Object callerContext) {    DraweeController controller = mSimpleDraweeControllerBuilder        .setCallerContext(callerContext)        .setUri(uri)        .setOldController(getController())        .build();    setController(controller);  }}

SimpleDraweeView在init()方法中调用sDraweeControllerBuilderSupplier.get(),把结果赋给了成员变量mSimpleDraweeControllerBuilder,
来看一下它的get()方法:(PipelineDraweeControllerBuilder.java)

@Overridepublic PipelineDraweeControllerBuilder get() {  return new PipelineDraweeControllerBuilder(      mContext,      mPipelineDraweeControllerFactory,      mImagePipeline,      mBoundControllerListeners);}

创建出PipelineDraweeControllerBuilder,主要需要PipelineDraweeControllerFactory和ImagePipeline参数。
这里的mSimpleDraweeControllerBuilder的类型其实就是PipelineDraweeControllerBuilder

首先看一下PipelineDraweeControllerBuilder的继承关系:
enter image description here

SimpleDraweeControllerBuilder是最上层的接口,暴露了最基本的5个方法,设置context,设置uri,复用controller,生成controller.
AbstractDraweeControllerBuilder是基本实现

2.setImageUri

setImageURI是Fresco加载图片的唯一方法 (SimpleDraweeView.java)

/**  * Displays an image given by the uri.  *  * @param uri uri of the image  * @param callerContext caller context  */  public void setImageURI(Uri uri, @Nullable Object callerContext) {    DraweeController controller = mSimpleDraweeControllerBuilder        .setCallerContext(callerContext)        .setUri(uri)        .setOldController(getController())        .build();    setController(controller);  }

mSimpleDraweeControllerBuilder从之前的代码中可以看出,它的类型是PipelineDraweeControllerBuilder。

1.mSimpleDraweeControllerBuilder.build()

首先是build()方法,具体调用在父类AbstractDraweeControllerBuilder中:(AbstractDraweeControllerBuilder.java)

/** Builds the specified controller. */@Overridepublic AbstractDraweeController build() {  validate();  // if only a low-res request is specified, treat it as a final request.  if (mImageRequest == null && mMultiImageRequests == null && mLowResImageRequest != null) {    mImageRequest = mLowResImageRequest;    mLowResImageRequest = null;  }  return buildController();}/** Builds a regular controller. */protected AbstractDraweeController buildController() {  AbstractDraweeController controller = obtainController();  controller.setRetainImageOnFailure(getRetainImageOnFailure());  //失败时是否显示上一次加载的图片。默认为false  maybeBuildAndSetRetryManager(controller);  //是否增加点击重试  TODO  maybeAttachListeners(controller);  return controller;}/** Concrete builder classes should override this method to return a new controller. */protected abstract AbstractDraweeController obtainController();  //具体的子类实现

build方法会对成员变量进行赋值,然后调用buildController()

buildController调用obtainController(),然后增加失败时是否显示上一张图片和点击重试加载的逻辑,最后返回controller

obtainController是abstract的,具体实现在子类PipelineDraweeControllerBuilder中,

看一下PipelineDraweeControllerBuilder的具体实现:(PipelineDraweeControllerBuilder.java)

private final ImagePipeline mImagePipeline;private final PipelineDraweeControllerFactory mPipelineDraweeControllerFactory;public PipelineDraweeControllerBuilder(    Context context,    PipelineDraweeControllerFactory pipelineDraweeControllerFactory,    ImagePipeline imagePipeline,    Set<ControllerListener> boundControllerListeners) {  super(context, boundControllerListeners);  mImagePipeline = imagePipeline;  mPipelineDraweeControllerFactory = pipelineDraweeControllerFactory;}@Overrideprotected PipelineDraweeController obtainController() {  DraweeController oldController = getOldController();  PipelineDraweeController controller;  if (oldController instanceof PipelineDraweeController) {  //复用old controller    controller = (PipelineDraweeController) oldController;    controller.initialize(        obtainDataSourceSupplier(),        generateUniqueControllerId(),        getCallerContext());  } else {   //new controller    controller = mPipelineDraweeControllerFactory.newController(        obtainDataSourceSupplier(),        generateUniqueControllerId(),        getCallerContext());  }  return controller;}

注意这里的代码27行,obtainDataSourceSupplier(),这个方法创建了DataSource,后边再说。

先讲一下PipelineDraweeControllerBuilder的初始化过程:

Fresco.initialize(context)
—>Fresco.initializeDrawee(context)
—>new PipelineDraweeControllerBuilderSupplier(),构造函数中同时new了PipelineDraweeControllerFactory,该工厂类用于new PipelineDraweeController (PipelineDraweeControllerFactory.java)

public PipelineDraweeController newController(    Supplier<DataSource<CloseableReference<CloseableImage>>> dataSourceSupplier,    String id,    Object callerContext) {  return new PipelineDraweeController(      mResources,      mDeferredReleaser,      mAnimatedDrawableFactory,      mUiThreadExecutor,      dataSourceSupplier,      id,      callerContext);}

—>SimpleDraweeView.initialize(supplier),把supplier赋值给SimpleDraweeView
—>SimpleDraweeView.init(),调用supplier的get()方法生成了成员变量SimpleDraweeControllerBuilder mSimpleDraweeControllerBuilder

2.setController

首先看一下DraweeView,DraweeHolder,DraweeController,DraweeHierarchy的关系:
enter image description here
三者的关系如下图所示,DraweeView 会通过DraweeHolder把获得的 Event 转发给 Controller,然后 Controller 根据 Event 来决定是否需要显示和隐藏 图像(包括动画),而这些图像都存储在 Hierarchy 中,最后 DraweeView 绘制时直接通过 getTopLevelDrawable 就可以获取需要显示的图像。
enter image description here

DraweeView的setController调用的是父类的方法:(DraweeView.java)

/*** View that displays a {@link DraweeHierarchy}.** <p> Hierarchy should be set prior to using this view. See {@code setHierarchy}. Because creating* a hierarchy is an expensive operation, it is recommended this be done once per view, typically* near creation time.** <p> In order to display an image, controller has to be set. See {@code setController}.* <p> Although ImageView is subclassed instead of subclassing View directly, this class does not* support ImageView's setImageXxx, setScaleType and similar methods. Extending ImageView is a short* term solution in order to inherit some of its implementation (padding calculations, etc.).* This class is likely to be converted to extend View directly in the future, so avoid using* ImageView's methods and properties (T5856175).*/public class DraweeView<DH extends DraweeHierarchy> extends ImageView {     private DraweeHolder<DH> mDraweeHolder;     。。。/** Sets the controller. */public void setController(@Nullable DraweeController draweeController) {  mDraweeHolder.setController(draweeController);  super.setImageDrawable(mDraweeHolder.getTopLevelDrawable());}}

DraweeView中有成员变量mDraweeHolder,setController最终调用的mDraweeHolder的同名方法,另外会通过mDraweeHolder.getTopLevelDrawable()更新现在要显示的图片。

看一下DraweeHolder的setController方法:(DraweeHolder.java)

/*** Sets a new controller.*/public void setController(@Nullable DraweeController draweeController) {  boolean wasAttached = mIsControllerAttached;  if (wasAttached) {    detachController();  }  // Clear the old controller  if (mController != null) {    mEventTracker.recordEvent(Event.ON_CLEAR_OLD_CONTROLLER);    mController.setHierarchy(null);  }  mController = draweeController;  if (mController != null) {    mEventTracker.recordEvent(Event.ON_SET_CONTROLLER);    **mController.setHierarchy(mHierarchy);  } else {    mEventTracker.recordEvent(Event.ON_CLEAR_CONTROLLER);  }  if (wasAttached) {    attachController();  }}

看一下attachController()方法:(DraweeHolder.java)

private void attachController() {  if (mIsControllerAttached) {    return;  }  mEventTracker.recordEvent(Event.ON_ATTACH_CONTROLLER);  mIsControllerAttached = true;  if (mController != null &&      mController.getHierarchy() != null) {    mController.onAttach();  }}

调用了DraweeController的onAttach方法,具体实现在DraweeController的子类AbstractDraweeController中:(AbstractDraweeController.java)

@Overridepublic void onAttach() { ...  mDeferredReleaser.cancelDeferredRelease(this);  mIsAttached = true;  if (!mIsRequestSubmitted) {    submitRequest();  }}

1.AbstractDraweeController的submitRequest()

看一下AbstractDraweeController的submitRequest()方法:(AbstractDraweeController.java)

protected void submitRequest() {  final T closeableImage = getCachedImage();  if (closeableImage != null) {    mDataSource = null;    mIsRequestSubmitted = true;    mHasFetchFailed = false;    mEventTracker.recordEvent(Event.ON_SUBMIT_CACHE_HIT);    getControllerListener().onSubmit(mId, mCallerContext);    onNewResultInternal(mId, mDataSource, closeableImage, 1.0f, true, true);    return;  }  mEventTracker.recordEvent(Event.ON_DATASOURCE_SUBMIT);  getControllerListener().onSubmit(mId, mCallerContext);  mSettableDraweeHierarchy.setProgress(0, true);  mIsRequestSubmitted = true;  mHasFetchFailed = false;  mDataSource = getDataSource();  if (FLog.isLoggable(FLog.VERBOSE)) {    FLog.v(        TAG,        "controller %x %s: submitRequest: dataSource: %x",        System.identityHashCode(this),        mId,        System.identityHashCode(mDataSource));  }  final String id = mId;  final boolean wasImmediate = mDataSource.hasResult();  final DataSubscriber<T> dataSubscriber =      new BaseDataSubscriber<T>() {        @Override        public void onNewResultImpl(DataSource<T> dataSource) {          // isFinished must be obtained before image, otherwise we might set intermediate result          // as final image.          boolean isFinished = dataSource.isFinished();          float progress = dataSource.getProgress();          T image = dataSource.getResult();          if (image != null) {            onNewResultInternal(id, dataSource, image, progress, isFinished, wasImmediate);          } else if (isFinished) {            onFailureInternal(id, dataSource, new NullPointerException(), /* isFinished */ true);          }        }        @Override        public void onFailureImpl(DataSource<T> dataSource) {          onFailureInternal(id, dataSource, dataSource.getFailureCause(), /* isFinished */ true);        }        @Override        public void onProgressUpdate(DataSource<T> dataSource) {          boolean isFinished = dataSource.isFinished();          float progress = dataSource.getProgress();          onProgressUpdateInternal(id, dataSource, progress, isFinished);        }      };  mDataSource.subscribe(dataSubscriber, mUiThreadImmediateExecutor);}

17行getDataSource()给mDataSource变量赋值
28-53行,创建了观察者DataSubscriber
54行,执行订阅操作

2.DataSource 及DataSubscriber介绍

/** * An alternative to Java Futures for the image pipeline. * * <p>Unlike Futures, DataSource can issue a series of results, rather than just one. A prime * example is decoding progressive images, which have a series of intermediate results before the * final one. * * <p>DataSources MUST be closed (close() is called on the DataSource) else resources may leak. * *@param <T> the type of the result */public interface DataSource<T> {  /**   * @return true if the data source is closed, false otherwise   */  boolean isClosed();  /**   * The most recent result of the asynchronous computation.   *   * <p>The caller gains ownership of the object and is responsible for releasing it.   * Note that subsequent calls to getResult might give different results. Later results should be   * considered to be of higher quality.   *   * <p>This method will return null in the following cases:   * <ul>   * <li>when the DataSource does not have a result ({@code hasResult} returns false).   * <li>when the last result produced was null.   * </ul>   * @return current best result   */  @Nullable T getResult();  /**   * @return true if any result (possibly of lower quality) is available right now, false otherwise   */  boolean hasResult();  /**   * @return true if request is finished, false otherwise   */  boolean isFinished();  /**   * @return true if request finished due to error   */  boolean hasFailed();  /**   * @return failure cause if the source has failed, else null   */  @Nullable Throwable getFailureCause();  /**   * @return progress in range [0, 1]   */  float getProgress();  /**   * Cancels the ongoing request and releases all associated resources.   *   * <p>Subsequent calls to {@link #getResult} will return null.   * @return true if the data source is closed for the first time   */  boolean close();  /**   * Subscribe for notifications whenever the state of the DataSource changes.   *   * <p>All changes will be observed on the provided executor.   * @param dataSubscriber   * @param executor   */  void subscribe(DataSubscriber<T> dataSubscriber, Executor executor);}

下边看看DataSubscriber:

/** * Subscribes to DataSource<T>. * @param <T> */public interface DataSubscriber<T> {  /**   * Called whenever a new value is ready to be retrieved from the DataSource.   *   * <p>To retrieve the new value, call {@code dataSource.getResult()}.   *   * <p>To determine if the new value is the last, use {@code dataSource.isFinished()}.   *   * @param dataSource   */  void onNewResult(DataSource<T> dataSource);  /**   * Called whenever an error occurs inside of the pipeline.   *   * <p>No further results will be produced after this method is called.   *   * <p>The throwable resulting from the failure can be obtained using   * {@code dataSource.getFailureCause}.   *   * @param dataSource   */  void onFailure(DataSource<T> dataSource);  /**   * Called whenever the request is cancelled (a request being cancelled means that is was closed   * before it finished).   *   * <p>No further results will be produced after this method is called.   *   * @param dataSource   */  void onCancellation(DataSource<T> dataSource);  /**   * Called when the progress updates.   *   * @param dataSource   */  void onProgressUpdate(DataSource<T> dataSource);}

DataSubscriber有1个base实现,BaseDataSubscriber:

/** * Base implementation of {@link DataSubscriber} that ensures that the data source is closed when * the subscriber has finished with it. * <p> * Sample usage: * <pre> * <code> * dataSource.subscribe( *   new BaseDataSubscriber() { *     {@literal @}Override *     public void onNewResultImpl(DataSource dataSource) { *       // Store image ref to be released later. *       mCloseableImageRef = dataSource.getResult(); *       // Use the image. *       updateImage(mCloseableImageRef); *       // No need to do any cleanup of the data source. *     } * *     {@literal @}Override *     public void onFailureImpl(DataSource dataSource) { *       // No cleanup of the data source required here. *     } *   }); * </code> * </pre> */public abstract class BaseDataSubscriber<T> implements DataSubscriber<T> {  @Override  public void onNewResult(DataSource<T> dataSource) {    // isFinished() should be checked before calling onNewResultImpl(), otherwise    // there would be a race condition: the final data source result might be ready before    // we call isFinished() here, which would lead to the loss of the final result    // (because of an early dataSource.close() call).    final boolean shouldClose = dataSource.isFinished();    try {      onNewResultImpl(dataSource);    } finally {      if (shouldClose) {        dataSource.close();      }    }  }  @Override  public void onFailure(DataSource<T> dataSource) {    try {      onFailureImpl(dataSource);    } finally {      dataSource.close();    }  }  @Override  public void onCancellation(DataSource<T> dataSource) {  }  @Override  public void onProgressUpdate(DataSource<T> dataSource) {  }  protected abstract void onNewResultImpl(DataSource<T> dataSource);  protected abstract void onFailureImpl(DataSource<T> dataSource);}

DataSource 是一个 interface, 功能与JDK中的Future类似,但是相比于Future,它的先进之处则在于 不仅仅只生产一个单一的结果,而是能够提供系列结果。

Unlike Futures, DataSource can issue a series of results, rather than just one.

最典型的用途就是渐进式加载图片时可以提供加载中的中间数据。

DataSubscriber 和 DataSource 构成了一个观察者模式。

Datasource 提供了注册方法。

void subscribe(DataSubscriber dataSubscriber, Executor executor);

通过 subscribe 方法我们可以把 DataSubscriber 注册成为 DataSource 的观察者,然后当 DataSource 的数据发生变化时,在 Executor 中通知所有的观察者 - DataSubscriber。

DataSubscriber 会响应数据的四种变化。

  • onNewResult
  • onFailure
  • onCancellation
  • onProgressUpdate

使用Executor来通知观察者是比较高明的,这样做可以让回调方法的执行线程交由 DataSubscriber 来处理,增加了灵活性。

AbstractDataSource是DataSource的抽象实现,它管理了事件的各种状态,并且当状态变化时,会发送通知。
官方也建议其他的DataSource都继承AbstractDataSource

/** * An abstract implementation of {@link DataSource} interface. * * <p> It is highly recommended that other data sources extend this class as it takes care of the * state, as well as of notifying listeners when the state changes. * * <p> Subclasses should override {@link #closeResult(T result)} if results need clean up * * @param <T> */public abstract class AbstractDataSource<T> implements DataSource<T> {  /**   * Describes state of data source   */  private enum DataSourceStatus {    // data source has not finished yet    IN_PROGRESS,    // data source has finished with success    SUCCESS,    // data source has finished with failure    FAILURE,  }

看一下subscribe方法的具体实现:(AbstractDataSource.java)

@Overridepublic void subscribe(final DataSubscriber<T> dataSubscriber, final Executor executor) {  Preconditions.checkNotNull(dataSubscriber);  Preconditions.checkNotNull(executor);  boolean shouldNotify;  synchronized(this) {    if (mIsClosed) {      return;    }    if (mDataSourceStatus == DataSourceStatus.IN_PROGRESS) {      mSubscribers.add(Pair.create(dataSubscriber, executor));    }    shouldNotify = hasResult() || isFinished() || wasCancelled();  }  if (shouldNotify) {    notifyDataSubscriber(dataSubscriber, executor, hasFailed(), wasCancelled());  }}private void notifyDataSubscriber(    final DataSubscriber<T> dataSubscriber,    final Executor executor,    final boolean isFailure,    final boolean isCancellation) {  executor.execute(      new Runnable() {        @Override        public void run() {          if (isFailure) {            dataSubscriber.onFailure(AbstractDataSource.this);          } else if (isCancellation) {            dataSubscriber.onCancellation(AbstractDataSource.this);          } else {            dataSubscriber.onNewResult(AbstractDataSource.this);          }        }      });}

notifyDataSubscriber方法中使用了executor,该参数中由subscribe方法传入,提高了通知方法的灵活性。

现在返回到AbstractDraweeController的submitRequest()方法:
17行getDataSource()给mDataSource变量赋值
28-53行,创建了观察者DataSubscriber
54行,执行订阅操作

getDataSource在AbstractDraweeController中是abstract的,具体实现在子类PipelineDraweeController中:(PipelineDraweeController.java)

private Supplier<DataSource<CloseableReference<CloseableImage>>> mDataSourceSupplier;public PipelineDraweeController(    Resources resources,    DeferredReleaser deferredReleaser,    AnimatedDrawableFactory animatedDrawableFactory,    Executor uiThreadExecutor,    MemoryCache<CacheKey, CloseableImage> memoryCache,    Supplier<DataSource<CloseableReference<CloseableImage>>> dataSourceSupplier,    String id,    CacheKey cacheKey,    Object callerContext) {    super(deferredReleaser, uiThreadExecutor, id, callerContext);  mResources = resources;  mAnimatedDrawableFactory = animatedDrawableFactory;  mMemoryCache = memoryCache;  mCacheKey = cacheKey;  init(dataSourceSupplier);}/*** Initializes this controller with the new data source supplier, id and caller context. This* allows for reusing of the existing controller instead of instantiating a new one. This method* should be called when the controller is in detached state.** @param dataSourceSupplier data source supplier* @param id unique id for this controller* @param callerContext tag and context for this controller*/public void initialize(    Supplier<DataSource<CloseableReference<CloseableImage>>> dataSourceSupplier,    String id,    CacheKey cacheKey,    Object callerContext) {   //该方法是复用old controller时调用的  super.initialize(id, callerContext);  init(dataSourceSupplier);  mCacheKey = cacheKey;}private void init(Supplier<DataSource<CloseableReference<CloseableImage>>> dataSourceSupplier) {  mDataSourceSupplier = dataSourceSupplier;}@Overrideprotected DataSource<CloseableReference<CloseableImage>> getDataSource() {  if (FLog.isLoggable(FLog.VERBOSE)) {    FLog.v(TAG, "controller %x: getDataSource", System.identityHashCode(this));  }  return mDataSourceSupplier.get();}

可以看出DataSourceSupplier的赋值是在初始化PipelineDraweeController时调用的,
PipelineDraweeController 初始化是什么时候呢?
回到SimpleDraweeView的setImageUri方法:

public void setImageURI(Uri uri, @Nullable Object callerContext) {    DraweeController controller = mSimpleDraweeControllerBuilder        .setCallerContext(callerContext)        .setUri(uri)        .setOldController(getController())        .build();    setController(controller);  }

这里创建了DraweeController,具体实现在PipelineDraweeControllerBuilder.java中

@Overrideprotected PipelineDraweeController obtainController() {  DraweeController oldController = getOldController();  PipelineDraweeController controller;  if (oldController instanceof PipelineDraweeController) {  //复用old controller    controller = (PipelineDraweeController) oldController;    controller.initialize(        obtainDataSourceSupplier(),        generateUniqueControllerId(),        getCallerContext());  } else {   //new controller    controller = mPipelineDraweeControllerFactory.newController(        obtainDataSourceSupplier(),        generateUniqueControllerId(),        getCallerContext());  }  return controller;}

上边提到过obtainDataSourceSupplier()方法,这个方法创建出了真正的DataSourceSupplier,具体实现在父类中:(AbstractDraweeControllerBuilder.java)

/** Gets the top-level data source supplier to be used by a controller. */protected Supplier<DataSource<IMAGE>> obtainDataSourceSupplier() {  if (mDataSourceSupplier != null) {    return mDataSourceSupplier;  }  Supplier<DataSource<IMAGE>> supplier = null;  // final image supplier;  if (mImageRequest != null) {    supplier = getDataSourceSupplierForRequest(mImageRequest);  } else if (mMultiImageRequests != null) {   //多个图片地址    supplier = getFirstAvailableDataSourceSupplier(mMultiImageRequests, mTryCacheOnlyFirst);  }  // increasing-quality supplier; highest-quality supplier goes first  if (supplier != null && mLowResImageRequest != null) {  //不同分辨率    List<Supplier<DataSource<IMAGE>>> suppliers = new ArrayList<>(2);    suppliers.add(supplier);    suppliers.add(getDataSourceSupplierForRequest(mLowResImageRequest));    supplier = IncreasingQualityDataSourceSupplier.create(suppliers);  }  // no image requests; use null data source supplier  if (supplier == null) {    supplier = DataSources.getFailedDataSourceSupplier(NO_REQUEST_EXCEPTION);  }  return supplier;}。。。/** Creates a data source supplier for the given image request. */protected Supplier<DataSource<IMAGE>> getDataSourceSupplierForRequest(REQUEST imageRequest) {  return getDataSourceSupplierForRequest(imageRequest, /* bitmapCacheOnly */ false);}/** Creates a data source supplier for the given image request. */protected Supplier<DataSource<IMAGE>> getDataSourceSupplierForRequest(    final REQUEST imageRequest,    final boolean bitmapCacheOnly) {  final Object callerContext = getCallerContext();  return new Supplier<DataSource<IMAGE>>() {    @Override    public DataSource<IMAGE> get() {      return getDataSourceForRequest(imageRequest, callerContext, bitmapCacheOnly);    }    @Override    public String toString() {      return Objects.toStringHelper(this)          .add("request", imageRequest.toString())          .toString();    }  };}。。。/*** Concrete builder classes should override this method to return a data source for the request.** <p/>IMPORTANT: Do NOT ever call this method directly. This method is only to be called from* a supplier created in {#code getDataSourceSupplierForRequest(REQUEST, boolean)}.** <p/>IMPORTANT: Make sure that you do NOT use any non-final field from this method, as the field* may change if the instance of this builder gets reused. If any such field is required, override* {#code getDataSourceSupplierForRequest(REQUEST, boolean)}, and store the field in a final* variable (same as it is done for callerContext).*/protected abstract DataSource<IMAGE> getDataSourceForRequest(    final REQUEST imageRequest,    final Object callerContext,    final boolean bitmapCacheOnly);
  1. 首先是11-13行,单个url地址的话肯定调用的是getDataSourceSupplierForRequest()
  2. 然后是34-36行,调用了它的重载方法
    3.下边的39-54行,new出一个Supplier,并暴露出抽象方法getDataSourceForRequest,需要子类实现

具体实现在子类中:(PipelineDraweeControllerBuilder.java)

@Overrideprotected DataSource<CloseableReference<CloseableImage>> getDataSourceForRequest(    ImageRequest imageRequest,    Object callerContext,    boolean bitmapCacheOnly) {  if (bitmapCacheOnly) {    return mImagePipeline.fetchImageFromBitmapCache(imageRequest, callerContext);  } else {    return mImagePipeline.fetchDecodedImage(imageRequest, callerContext);  }}

fetchImageFromBitmapCache是从缓存中获取中,暂时不看,我们需要研究的fetchDecodedImage,从网络获取。

3.ImagePipeline fetchDecodedImage

/*** Submits a request for execution and returns a DataSource representing the pending decoded* image(s).* <p>The returned DataSource must be closed once the client has finished with it.* @param imageRequest the request to submit* @return a DataSource representing the pending decoded image(s)*/public DataSource<CloseableReference<CloseableImage>> fetchDecodedImage(    ImageRequest imageRequest,    Object callerContext) {  try {    Producer<CloseableReference<CloseableImage>> producerSequence =        mProducerSequenceFactory.getDecodedImageProducerSequence(imageRequest);    return submitFetchRequest(        producerSequence,        imageRequest,        ImageRequest.RequestLevel.FULL_FETCH,        callerContext);  } catch (Exception exception) {    return DataSources.immediateFailedDataSource(exception);  }}

这里有两个关键步骤
1. mProducerSequenceFactory.getDecodedImageProducerSequence
2. submitFetchRequest

1.Producer和Consumer
/*** Building block for image processing in the image pipeline.** <p> Execution of image request consists of multiple different tasks such as network fetch,* disk caching, memory caching, decoding, applying transformations etc. Producer<T> represents* single task whose result is an instance of T. Breaking entire request into sequence of* Producers allows us to construct different requests while reusing the same blocks.** <p> Producer supports multiple values and streaming.** @param <T>*/public interface Producer<T> {  /**  * Start producing results for given context. Provided consumer is notified whenever progress is  * made (new value is ready or error occurs).  * @param consumer  * @param context  */  void produceResults(Consumer<T> consumer, ProducerContext context);}

fresco使用了Produer和Consumer的模式。
Producer用于执行各种不同的任务,如网络获取,硬盘缓存,内存缓存,解码等。通过produceResults方法把结果提供给消费者Consumer,
Consumer处理各种回调事件。

/*** Consumes data produced by {@link Producer}.<T>** <p> The producer uses this interface to notify its client when new data is ready or an error* occurs. Execution of the image request is structured as a sequence of Producers. Each one* consumes data produced by producer preceding it in the sequence.** <p>For example decode is a producer that consumes data produced by the disk cache get producer.** <p> The consumer is passed new intermediate results via onNewResult(isLast = false) method. Each* consumer should expect that one of the following methods will be called exactly once, as the very* last producer call:* <ul>*  <li> onNewResult(isLast = true) if producer finishes successfully with a final result </li>*  <li> onFailure if producer failed to produce a final result </li>*  <li> onCancellation if producer was cancelled before a final result could be created </li>* </ul>** <p> Implementations of this interface must be thread safe, as callback methods might be called* on different threads.** @param <T>*/public interface Consumer<T> {  /**  * Called by a producer whenever new data is produced. This method should not throw an exception.  *  * <p> In case when result is closeable resource producer will close it after onNewResult returns.  * Consumer needs to make copy of it if the resource must be accessed after that. Fortunately,  * with CloseableReferences, that should not impose too much overhead.  *  * @param newResult  * @param isLast true if newResult is the last result  */  void onNewResult(T newResult, boolean isLast);  /**  * Called by a producer whenever it terminates further work due to Throwable being thrown. This  * method should not throw an exception.  *  * @param t  */  void onFailure(Throwable t);  /**  * Called by a producer whenever it is cancelled and won't produce any more results  */  void onCancellation();  /**  * Called when the progress updates.  *  * @param progress in range [0, 1]  */  void onProgressUpdate(float progress);}
  • onNewResult(isLast = true) if producer finishes successfully with a final result
  • onFailure if producer failed to produce a final result
  • onCancellation if producer was cancelled before a final result could be created

Producer成功完成的时候,回调Consumer的onNewResult方法;失败时回调onFailure方法;取消的话,回调onCancellation方法。
Consumer有一个base实现类BaseConsumer,对异常状况进行了封装处理:

/** * Base implementation of Consumer that implements error handling conforming to the * Consumer's contract. * * <p> This class also prevents execution of callbacks if one of final methods was called before: * onFinish(isLast = true), onFailure or onCancellation. * * <p> All callbacks are executed within a synchronized block, so that clients can act as if all * callbacks are called on single thread. * * @param <T> */@ThreadSafepublic abstract class BaseConsumer<T> implements Consumer<T> {  /**   * Set to true when onNewResult(isLast = true), onFailure or onCancellation is called. Further   * calls to any of the 3 methods are not propagated   */  private boolean mIsFinished;  public BaseConsumer() {    mIsFinished = false;  }  @Override  public synchronized void onNewResult(@Nullable T newResult, boolean isLast) {    if (mIsFinished) {      return;    }    mIsFinished = isLast;    try {      onNewResultImpl(newResult, isLast);    } catch (Exception e) {      onUnhandledException(e);    }  }  @Override  public synchronized void onFailure(Throwable t) {    if (mIsFinished) {      return;    }    mIsFinished = true;    try {      onFailureImpl(t);    } catch (Exception e) {      onUnhandledException(e);    }  }  @Override  public synchronized void onCancellation() {    if (mIsFinished) {      return;    }    mIsFinished = true;    try {      onCancellationImpl();    } catch (Exception e) {      onUnhandledException(e);    }  }  /**   * Called when the progress updates.   *   * @param progress in range [0, 1]   */  @Override  public synchronized void onProgressUpdate(float progress) {    if (mIsFinished) {      return;    }    try {      onProgressUpdateImpl(progress);    } catch (Exception e) {      onUnhandledException(e);    }  }  /**   * Called by onNewResult, override this method instead.   */  protected abstract void onNewResultImpl(T newResult, boolean isLast);  /**   * Called by onFailure, override this method instead   */  protected abstract void onFailureImpl(Throwable t);  /**   * Called by onCancellation, override this method instead   */  protected abstract void onCancellationImpl();  /**   * Called when the progress updates   */  protected void onProgressUpdateImpl(float progress) {  }  /**   * Called whenever onNewResultImpl or onFailureImpl throw an exception   */  protected void onUnhandledException(Exception e) {    FLog.wtf(this.getClass(), "unhandled exception", e);  }}

BaseConsumer暴露出几个抽象方法:onNewResultImpl,onFailureImpl,onCancellationImpl,onProgressUpdateImpl在不同的时机被调用。
Producer模式,在Fresco中请求产生这块,用到了大量的这种概念,将网络数据的获取,磁盘缓存获取,内存缓存获取,解码,编码和图片的变换等等的处理,分为模块处理,并以倒叙的方式联合再一起调用。显得格外的高大上,就是初次见有点难以理解。

public interface Producer {
void produceResults(Consumer consumer, ProducerContext context);
}

Producer作为一个行为,表示的是生产结果。有了结果就要处理,而produceResults()方法就代表处理结果,那么是谁处理结果我们不知道,所以就由参数传入,故而就有了消费者Consumer。

而Producer的处理模式在Fresco中表现的也比较奇特,由于网络数据的获取,磁盘缓存获取,内存缓存获取,解码,编码和图片等这些操作是一个流程处理,那么如何将流程性的东西和Producer结合起来呢?

为了成为一个链式,会有如下的代码模式:

public class XXProducer implements Producer {  private final Producer mInputProducer;  public XXProducer (Producer inputProducer) {    mInputProducer = inputProducer;  }  @Override  public void produceResults(Consumer consumer, ProducerContext context) {    ....//首先执行自己的业务逻辑,如果不满足要求,再往上传递,执行mInputProducer的逻辑    mInputProducer.produceResults(consumer, context);  }}

接收一个外部的生产者,并在自身处理结果方法的最后调用外部生产者处理结果的方法。

这样看似先创建外部的生产者,但是实际上最后才调用外部的生产者。所以Fresco实例的创建和反向调用就好像这个样子:
enter image description here

2.mProducerSequenceFactory.getDecodedImageProducerSequence

首先看一下mProducerSequenceFactory 的由来:(ImagePipeline.java)

private final ProducerSequenceFactory mProducerSequenceFactory;public ImagePipeline(    ProducerSequenceFactory producerSequenceFactory,    Set<RequestListener> requestListeners,    Supplier<Boolean> isPrefetchEnabledSupplier,    MemoryCache<CacheKey, CloseableImage> bitmapMemoryCache,    MemoryCache<CacheKey, PooledByteBuffer> encodedMemoryCache,    BufferedDiskCache mainBufferedDiskCache,    BufferedDiskCache smallImageBufferedDiskCache,    CacheKeyFactory cacheKeyFactory,    ThreadHandoffProducerQueue threadHandoffProducerQueue) {  mIdCounter = new AtomicLong();  mProducerSequenceFactory = producerSequenceFactory;  mRequestListener = new ForwardingRequestListener(requestListeners);  mIsPrefetchEnabledSupplier = isPrefetchEnabledSupplier;  mBitmapMemoryCache = bitmapMemoryCache;  mEncodedMemoryCache = encodedMemoryCache;  mMainBufferedDiskCache = mainBufferedDiskCache;  mSmallImageBufferedDiskCache = smallImageBufferedDiskCache;  mCacheKeyFactory = cacheKeyFactory;  mThreadHandoffProducerQueue = threadHandoffProducerQueue;}

看一下ImagePipeline构造函数的调用:(ImagePipelineFactory.java)

public ImagePipeline getImagePipeline() {  if (mImagePipeline == null) {    mImagePipeline =        new ImagePipeline(            getProducerSequenceFactory(),            mConfig.getRequestListeners(),            mConfig.getIsPrefetchEnabledSupplier(),            getBitmapMemoryCache(),            getEncodedMemoryCache(),            getMainBufferedDiskCache(),            getSmallImageBufferedDiskCache(),            mConfig.getCacheKeyFactory(),            mThreadHandoffProducerQueue);  }  return mImagePipeline;}private final ImagePipelineConfig mConfig;private ProducerFactory mProducerFactory;private ProducerSequenceFactory mProducerSequenceFactory;private ProducerSequenceFactory getProducerSequenceFactory() {  if (mProducerSequenceFactory == null) {    mProducerSequenceFactory =        new ProducerSequenceFactory(            getProducerFactory(),            mConfig.getNetworkFetcher(),            mConfig.isResizeAndRotateEnabledForNetwork(),            mConfig.isDownsampleEnabled(),            mConfig.isWebpSupportEnabled(),            mThreadHandoffProducerQueue);  }  return mProducerSequenceFactory;}private ProducerFactory getProducerFactory() {  if (mProducerFactory == null) {    mProducerFactory =        new ProducerFactory(            mConfig.getContext(),            mConfig.getPoolFactory().getSmallByteArrayPool(),            getImageDecoder(),            mConfig.getProgressiveJpegConfig(),            mConfig.isDownsampleEnabled(),            mConfig.isResizeAndRotateEnabledForNetwork(),            mConfig.getExecutorSupplier(),            mConfig.getPoolFactory().getPooledByteBufferFactory(),            getBitmapMemoryCache(),            getEncodedMemoryCache(),            getMainBufferedDiskCache(),            getSmallImageBufferedDiskCache(),            mConfig.getCacheKeyFactory(),            getPlatformBitmapFactory(),            mConfig.isDecodeFileDescriptorEnabled());  }  return mProducerFactory;}

ProducerSequenceFactory提供了创建produer序列的方法
ProducerFactory提供了各种producer的构造方法
Producer用于执行各种不同的任务,如网络获取,硬盘缓存,内存缓存,解码等。
Producer会提供结果给消费者Consumer

回到mProducerSequenceFactory.getDecodedImageProducerSequence方法实现((ProducerSequenceFactory.java))

/*** Returns a sequence that can be used for a request for a decoded image.** @param imageRequest the request that will be submitted* @return the sequence that should be used to process the request*/public Producer<CloseableReference<CloseableImage>> getDecodedImageProducerSequence(    ImageRequest imageRequest) {  Producer<CloseableReference<CloseableImage>> pipelineSequence =      getBasicDecodedImageSequence(imageRequest);  if (imageRequest.getPostprocessor() != null) {    return getPostprocessorSequence(pipelineSequence);  //图片后处理,暂时不考虑  } else {    return pipelineSequence;  }}

主要调用是10行的getBasicDecodedImageSequence方法,12行的getPostprocessorSequence暂时不研究

ProducerSequence的执行顺序:

  1. BitmapMemoryCacheGetProducer 只读内存缓存的producer

  2. ThreadHandoffProducer 启动线程的producer,后续的producer都在线程中执行

  3. BitmapMemoryCacheKeyMultiplexProducer 使用memory cache key合并请求的producer

  4. BitmapMemoryCacheProducer 读取内存缓存的producer

  5. DecodeProducer 解码图片的producer,渐进式JPEG图片,gif和webp等动画图片的解码

  6. ResizeAndRotateProducer JPEG图片resizes和rotates处理

  7. AddImageTransformMetaDataProducer 主要包装解码的consumer,并传递到下一个producer

  8. EncodedCacheKeyMultiplexProducer 使用encoded cache key合并请求的producer

  9. EncodedMemoryCacheProducer 读取未解码的内存缓存的producer

  10. DiskCacheProducer 读取磁盘缓存的producer

  11. WebpTranscodeProducer 包装转码WebP到JPEG/PNG的consumer,并传递到下一个producer

  12. NetworkFetchProducer 网络请求的producer

    swallow result if prefetch -> bitmap cache get -> background thread hand-off -> multiplex -> bitmap cache -> decode ->
    multiplex ->encoded cache -> disk cache -> (webp transcode) -> network fetch

mProducerSequenceFactory.getDecodedImageProducerSequence解析:
1 —>getBasicDecodedImageSequence
2—>getNetworkFetchSequence
2.1 —>newBitmapCacheGetToDecodeSequence() //Bitmap cache get -> thread hand off -> multiplex -> bitmap cache—>decode
2.1.1—>newBitmapCacheGetToBitmapCacheSequence //Bitmap cache get -> thread hand off -> multiplex -> bitmap cache
2.1.1.1—>mProducerFactory.newBitmapMemoryCacheGetProducer //Bitmap cache get
2.1.1.2—>mProducerFactory.newBackgroundThreadHandoffProducer //thread hand off
2.1.1.3—>mProducerFactory.newBitmapMemoryCacheKeyMultiplexProducer // multiplex
2.1.1.4—>mProducerFactory.newBitmapMemoryCacheProducer //bitmap cache
2.1.2—> mProducerFactory.newDecodeProducer // decode
2.2—>getCommonNetworkFetchToEncodedMemorySequence() //multiplex -> encoded cache -> disk cache -> (webp transcode) -> network fetch.
2.2.1—>newEncodedCacheMultiplexToTranscodeSequence ///multiplex -> encoded cache -> disk cache -> (webp transcode)
2.2.1.1—>mProducerFactory.newEncodedCacheKeyMultiplexProducer //multiplex
2.2.1.2—>mProducerFactory.newEncodedMemoryCacheProducer //encoded cache
2.2.1.3—>mProducerFactory.newDiskCacheProducer //disk cache
2.2.1.4—>mProducerFactory.newWebpTranscodeProducer //(webp transcode)
2.2.2—>mProducerFactory.newNetworkFetchProducer //network fetch

首先看下getBasicDecodedImageSequence方法:(ProducerSequenceFactory.java)

private Producer<CloseableReference<CloseableImage>> getBasicDecodedImageSequence(    ImageRequest imageRequest) {  Preconditions.checkNotNull(imageRequest);  Uri uri = imageRequest.getSourceUri();  Preconditions.checkNotNull(uri, "Uri is null.");  if (UriUtil.isNetworkUri(uri)) {    return getNetworkFetchSequence();   //获取网络sequence  } else if (UriUtil.isLocalFileUri(uri)) {    if (MediaUtils.isVideo(MediaUtils.extractMime(uri.getPath()))) {      return getLocalVideoFileFetchSequence();    } else {      return getLocalImageFileFetchSequence();    }  } else if (UriUtil.isLocalContentUri(uri)) {    return getLocalContentUriFetchSequence();  } else if (UriUtil.isLocalAssetUri(uri)) {    return getLocalAssetFetchSequence();  } else if (UriUtil.isLocalResourceUri(uri)) {    return getLocalResourceFetchSequence();  } else if (UriUtil.isDataUri(uri)) {    return getDataFetchSequence();  } else {    String uriString = uri.toString();    if (uriString.length() > 30) {      uriString = uriString.substring(0, 30) + "...";    }    throw new RuntimeException("Unsupported uri scheme! Uri is: " + uriString);  }}

这个方法里,会根据不同的Uri进行不同处理,我们需要关注的是第8行getNetworkFetchSequence,(ProducerSequenceFactory.java)

/**   * swallow result if prefetch -> bitmap cache get ->   * background thread hand-off -> multiplex -> bitmap cache -> decode -> multiplex ->   * encoded cache -> disk cache -> (webp transcode) -> network fetch.   */  private synchronized Producer<CloseableReference<CloseableImage>> getNetworkFetchSequence() {    if (mNetworkFetchSequence == null) {      mNetworkFetchSequence =          newBitmapCacheGetToDecodeSequence(getCommonNetworkFetchToEncodedMemorySequence());    }    return mNetworkFetchSequence;  }

这里分为两部分,
1. newBitmapCacheGetToDecodeSequence
( bitmap cache get ->background thread hand-off -> multiplex -> bitmap cache -> decode)
2. getCommonNetworkFetchToEncodedMemorySequence
(multiplex ->encoded cache -> disk cache -> (webp transcode) -> network fetch)

1.newBitmapCacheGetToDecodeSequence

bitmap cache get ->background thread hand-off -> multiplex -> bitmap cache -> decode

/*** Same as {@code newBitmapCacheGetToBitmapCacheSequence} but with an extra DecodeProducer.* @param inputProducer producer providing the input to the decode* @return bitmap cache get to decode sequence*/private Producer<CloseableReference<CloseableImage>> newBitmapCacheGetToDecodeSequence(    Producer<EncodedImage> inputProducer) {  DecodeProducer decodeProducer = mProducerFactory.newDecodeProducer(inputProducer);  //decode  return newBitmapCacheGetToBitmapCacheSequence(decodeProducer);}

第8行new除了DecodeProducer,这个执行顺序是在newBitmapCacheGetToBitmapCacheSequence之后的

/** * Bitmap cache get -> thread hand off -> multiplex -> bitmap cache * @param inputProducer producer providing the input to the bitmap cache * @return bitmap cache get to bitmap cache sequence */private Producer<CloseableReference<CloseableImage>> newBitmapCacheGetToBitmapCacheSequence(    Producer<CloseableReference<CloseableImage>> inputProducer) {  BitmapMemoryCacheProducer bitmapMemoryCacheProducer =      mProducerFactory.newBitmapMemoryCacheProducer(inputProducer);   //bitmap cache  BitmapMemoryCacheKeyMultiplexProducer bitmapKeyMultiplexProducer =      mProducerFactory.newBitmapMemoryCacheKeyMultiplexProducer(bitmapMemoryCacheProducer);  //multiplex  ThreadHandoffProducer<CloseableReference<CloseableImage>> threadHandoffProducer =      mProducerFactory.newBackgroundThreadHandoffProducer(   //thread hand off          bitmapKeyMultiplexProducer,          mThreadHandoffProducerQueue);  return mProducerFactory.newBitmapMemoryCacheGetProducer(threadHandoffProducer);   //Bitmap cache get}
  1. BitmapMemoryCacheGetProducer 只读内存缓存的producer
  2. ThreadHandoffProducer 启动线程的producer,后续的producer都在线程中执行
  3. BitmapMemoryCacheKeyMultiplexProducer 使用memory cache key合并请求的producer
  4. BitmapMemoryCacheProducer 读取内存缓存的producer
  5. DecodeProducer 解码图片的producer,渐进式JPEG图片,gif和webp等动画图片的解码
2.getCommonNetworkFetchToEncodedMemorySequence

multiplex ->encoded cache -> disk cache -> (webp transcode) -> network fetch

/*** multiplex -> encoded cache -> disk cache -> (webp transcode) -> network fetch.*/private synchronized Producer<EncodedImage> getCommonNetworkFetchToEncodedMemorySequence() {  if (mCommonNetworkFetchToEncodedMemorySequence == null) {    Producer<EncodedImage> inputProducer =        newEncodedCacheMultiplexToTranscodeSequence(            mProducerFactory.newNetworkFetchProducer(mNetworkFetcher));   //network fetch    mCommonNetworkFetchToEncodedMemorySequence =        ProducerFactory.newAddImageTransformMetaDataProducer(inputProducer);//AddImageTransformMetaDataProducer    主要包装解码的consumer,并传递到下一个producer    if (mResizeAndRotateEnabledForNetwork && !mDownsampleEnabled) {      mCommonNetworkFetchToEncodedMemorySequence =          mProducerFactory.newResizeAndRotateProducer(              mCommonNetworkFetchToEncodedMemorySequence);              //ResizeAndRotateProducer    JPEG图片resizes和rotates处理    }  }  return mCommonNetworkFetchToEncodedMemorySequence;}

第8行的mProducerFactory.newNetworkFetchProducer肯定是最后执行的
第7行的newEncodedCacheMultiplexToTranscodeSequence在newNetworkFetchProducer之前执行
第10行和第14行在newEncodedCacheMultiplexToTranscodeSequence之前执行

看一下newEncodedCacheMultiplexToTranscodeSequence的实现:

/** * encoded cache multiplex -> encoded cache -> (disk cache) -> (webp transcode) * @param inputProducer producer providing the input to the transcode * @return encoded cache multiplex to webp transcode sequence */private Producer<EncodedImage> newEncodedCacheMultiplexToTranscodeSequence(        Producer<EncodedImage> inputProducer) {  if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2 && !mWebpSupportEnabled) {    inputProducer = mProducerFactory.newWebpTranscodeProducer(inputProducer);//处理webp图片,可选  }  inputProducer = mProducerFactory.newDiskCacheProducer(inputProducer);//硬盘缓存producer  EncodedMemoryCacheProducer encodedMemoryCacheProducer =      mProducerFactory.newEncodedMemoryCacheProducer(inputProducer);//未解码的内存缓存  return mProducerFactory.newEncodedCacheKeyMultiplexProducer(encodedMemoryCacheProducer);//使用encoded cache key合并请求的producer}
  1. ResizeAndRotateProducer JPEG图片resizes和rotates处理

  2. AddImageTransformMetaDataProducer 主要包装解码的consumer,并传递到下一个producer

  3. EncodedCacheKeyMultiplexProducer 使用encoded cache key合并请求的producer

  4. EncodedMemoryCacheProducer 读取未解码的内存缓存的producer

  5. DiskCacheProducer 读取磁盘缓存的producer

  6. WebpTranscodeProducer 包装转码WebP到JPEG/PNG的consumer,并传递到下一个producer

  7. NetworkFetchProducer 网络请求的producer

综上所述,所有的流程,最先执行的肯定是最后创建的producer
1. BitmapMemoryCacheGetProducer 只读内存缓存的mProducerFactory.newBitmapMemoryCacheGetProducer

public BitmapMemoryCacheGetProducer newBitmapMemoryCacheGetProducer(      Producer<CloseableReference<CloseableImage>> inputProducer) {    return new BitmapMemoryCacheGetProducer(mBitmapMemoryCache, mCacheKeyFactory, inputProducer);  }

看一下BitmapMemoryCacheGetProducer这个类:

/** * Bitmap memory cache producer that is read-only. */public class BitmapMemoryCacheGetProducer extends BitmapMemoryCacheProducer {  @VisibleForTesting static final String PRODUCER_NAME = "BitmapMemoryCacheGetProducer";  public BitmapMemoryCacheGetProducer(      MemoryCache<CacheKey, CloseableImage> memoryCache,      CacheKeyFactory cacheKeyFactory,      Producer<CloseableReference<CloseableImage>> inputProducer) {    super(memoryCache, cacheKeyFactory, inputProducer);  }  @Override  protected Consumer<CloseableReference<CloseableImage>> wrapConsumer(      final Consumer<CloseableReference<CloseableImage>> consumer,      final CacheKey cacheKey) {    // since this cache is read-only, we can pass our consumer directly to the next producer    return consumer;  }  @Override  protected String getProducerName() {    return PRODUCER_NAME;  }}

这个类里没有什么操作,看一下它的父类BitmapMemoryCacheProducer:

public class BitmapMemoryCacheProducer implements Producer<CloseableReference<CloseableImage>> {  private final MemoryCache<CacheKey, CloseableImage> mMemoryCache;  private final CacheKeyFactory mCacheKeyFactory;  private final Producer<CloseableReference<CloseableImage>> mInputProducer;public BitmapMemoryCacheProducer(    MemoryCache<CacheKey, CloseableImage> memoryCache,    CacheKeyFactory cacheKeyFactory,    Producer<CloseableReference<CloseableImage>> inputProducer) {  mMemoryCache = memoryCache;  mCacheKeyFactory = cacheKeyFactory;  mInputProducer = inputProducer;}  @Override  public void produceResults(      final Consumer<CloseableReference<CloseableImage>> consumer,      final ProducerContext producerContext) {      ...    if (producerContext.getLowestPermittedRequestLevel().getValue() >=        ImageRequest.RequestLevel.BITMAP_MEMORY_CACHE.getValue()) {      listener.onProducerFinishWithSuccess(          requestId,          getProducerName(),          listener.requiresExtraMap(requestId) ? ImmutableMap.of(VALUE_FOUND, "false") : null);      consumer.onNewResult(null, true);      return;    }    Consumer<CloseableReference<CloseableImage>> wrappedConsumer = wrapConsumer(consumer, cacheKey);    …….    mInputProducer.produceResults(wrappedConsumer, producerContext);//传递Producer  }

produceResults会回调consumer.onNewResult方法,如果没有取得需要的结果,会依次调用上一层的结果produceResults。。。。,
注意这里的32行wrapConsumer,使用了代理模式,每个producer都会调用consumer的方法,但是不同的producer需要在原有consumer的基础上处理自己的一些逻辑,这里呢?就需要将原来的consumer进行代理,调用时,先处理自己的逻辑,然后调用原有consumer的相关方法即可。

有了下一步调用的produceResults()方法,那么哪里才是第一次调用produceResults()的地方呢? 这个地方肯定就是这一系列请求最先开始的地方.另外Consumer是什么时候创建的,怎么处理Producer产生的结果,这里就需要看一下submitFetchRequest方法了。

3.submitFetchRequest

(ImagePipeline.java)

/*** Submits a request for execution and returns a DataSource representing the pending decoded* image(s).* <p>The returned DataSource must be closed once the client has finished with it.* @param imageRequest the request to submit* @return a DataSource representing the pending decoded image(s)*/public DataSource<CloseableReference<CloseableImage>> fetchDecodedImage(    ImageRequest imageRequest,    Object callerContext) {  try {    Producer<CloseableReference<CloseableImage>> producerSequence =        mProducerSequenceFactory.getDecodedImageProducerSequence(imageRequest);//这里的Producer肯定就是上边分析的BitmapMemoryCacheProducer    return submitFetchRequest(        producerSequence,        imageRequest,        ImageRequest.RequestLevel.FULL_FETCH,        callerContext);  } catch (Exception exception) {    return DataSources.immediateFailedDataSource(exception);  }}private <T> DataSource<CloseableReference<T>> submitFetchRequest(    Producer<CloseableReference<T>> producerSequence,    ImageRequest imageRequest,    ImageRequest.RequestLevel lowestPermittedRequestLevelOnSubmit,    Object callerContext) {  try {    ImageRequest.RequestLevel lowestPermittedRequestLevel =        ImageRequest.RequestLevel.getMax(            imageRequest.getLowestPermittedRequestLevel(),            lowestPermittedRequestLevelOnSubmit);    SettableProducerContext settableProducerContext = new SettableProducerContext(        imageRequest,        generateUniqueFutureId(),        mRequestListener,        callerContext,        lowestPermittedRequestLevel,      /* isPrefetch */ false,        imageRequest.getProgressiveRenderingEnabled() ||            !UriUtil.isNetworkUri(imageRequest.getSourceUri()),        imageRequest.getPriority());    return CloseableProducerToDataSourceAdapter.create(        producerSequence,        settableProducerContext,        mRequestListener);  } catch (Exception exception) {    return DataSources.immediateFailedDataSource(exception);  }}

这里有个adapter:CloseableProducerToDataSourceAdapter,看一下这个类:

/*** DataSource<CloseableReference<T>> backed by a Producer<CloseableReference<T>** @param <T>*/@ThreadSafepublic class CloseableProducerToDataSourceAdapter<T    extends AbstractProducerToDataSourceAdapter<CloseableReference<T>> {  public static <T> DataSource<CloseableReference<T>> create(      Producer<CloseableReference<T>> producer,      SettableProducerContext settableProducerContext,      RequestListener listener) {    return new CloseableProducerToDataSourceAdapter<T>(        producer, settableProducerContext, listener);  }  private CloseableProducerToDataSourceAdapter(      Producer<CloseableReference<T>> producer,      SettableProducerContext settableProducerContext,      RequestListener listener) {    super(producer, settableProducerContext, listener);  }  @Override  @Nullable  public CloseableReference<T> getResult() {    return CloseableReference.cloneOrNull(super.getResult());  }  @Override  protected void closeResult(CloseableReference<T> result) {    CloseableReference.closeSafely(result);  }  @Override  protected void onNewResultImpl(CloseableReference<T> result, boolean isLast) {    super.onNewResultImpl(CloseableReference.cloneOrNull(result), isLast);  }}

这个类有没有很重要的逻辑,只有几个close方法,看一下它的父类AbstractProducerToDataSourceAdapter:

public abstract class AbstractProducerToDataSourceAdapter<T> extends AbstractDataSource<T> {//AbstractDataSource是DataSource的标准实现  private final SettableProducerContext mSettableProducerContext;  private final RequestListener mRequestListener;  protected AbstractProducerToDataSourceAdapter(      Producer<T> producer,      SettableProducerContext settableProducerContext,      RequestListener requestListener) {    mSettableProducerContext = settableProducerContext;    mRequestListener = requestListener;    mRequestListener.onRequestStart(        settableProducerContext.getImageRequest(),        mSettableProducerContext.getCallerContext(),        mSettableProducerContext.getId(),        mSettableProducerContext.isPrefetch());    producer.produceResults(createConsumer(), settableProducerContext);  //这里开始首次发送Producer的结果  }// 创建出Consumer  private Consumer<T> createConsumer() {    return new BaseConsumer<T>() {  //BaseConsumer是Consumer的base实现,处理了各种异常情况      @Override      protected void onNewResultImpl(@Nullable T newResult, boolean isLast) {//调用当前类的  onNewResultImpl方法 AbstractProducerToDataSourceAdapter.this.onNewResultImpl(newResult, isLast);      }      @Override      protected void onFailureImpl(Throwable throwable) {        AbstractProducerToDataSourceAdapter.this.onFailureImpl(throwable);      }      @Override      protected void onCancellationImpl() {        AbstractProducerToDataSourceAdapter.this.onCancellationImpl();      }      @Override      protected void onProgressUpdateImpl(float progress) {        AbstractProducerToDataSourceAdapter.this.setProgress(progress);      }    };  }   //consumer的回调  protected void onNewResultImpl(@Nullable T result, boolean isLast) {    if (super.setResult(result, isLast)) {      if (isLast) {        mRequestListener.onRequestSuccess(            mSettableProducerContext.getImageRequest(),            mSettableProducerContext.getId(),            mSettableProducerContext.isPrefetch());      }    }  }  private void onFailureImpl(Throwable throwable) {    if (super.setFailure(throwable)) {      mRequestListener.onRequestFailure(          mSettableProducerContext.getImageRequest(),          mSettableProducerContext.getId(),          throwable,          mSettableProducerContext.isPrefetch());    }  }  …...}
  1. AbstractProducerToDataSourceAdapter继承了AbstractDataSource,该类是DataSource的基本实现,说明AbstractProducerToDataSourceAdapter也是一个DataSource
  2. 构造方法的最后一行,producer.produceResults(createConsumer(), settableProducerContext,终于找到了producer的开始位置,这里的producer是由mProducerSequenceFactory.getDecodedImageProducerSequence的返回值传进来的,这里肯定就是BitmapMemoryCacheGetProducer
  3. 我们知道,Producer produceResults的时候,会回调BaseConsumer的onNewResultImpl方法,在这里的BaseConsumer的匿名实现类中,会回调AbstractProducerToDataSourceAdapter的同名方法,这里关注一下第48行super.setResult(result, isLast),我们看一下super类AbstractDataSource的实现:
 /**   * Subclasses should invoke this method to set the result to {@code value}.   *   * <p> This method will return {@code true} if the value was successfully set, or   * {@code false} if the data source has already been set, failed or closed.   *   * <p> If the value was successfully set and {@code isLast} is {@code true}, state of the   * data source will be set to {@link AbstractDataSource.DataSourceStatus#SUCCESS}.   *   * <p> {@link #closeResult} will be called for the previous result if the new value was   * successfully set, OR for the new result otherwise.   *   * <p> This will also notify the subscribers if the value was successfully set.   *   * <p> Do NOT call this method from a synchronized block as it invokes external code of the   * subscribers.   *   * @param value the value that was the result of the task.   * @param isLast whether or not the value is last.   * @return true if the value was successfully set.   */  protected boolean setResult(@Nullable T value, boolean isLast) {    boolean result = setResultInternal(value, isLast);    if (result) {      notifyDataSubscribers();    }    return result;  }

notifyDataSubscribers这正是我们想要的,发送通知给观察者,这里需要注意,需要在setResultInternal返回true时才会通知。看一下notifyDataSubscribers的实现:

  private void notifyDataSubscribers() {    final boolean isFailure = hasFailed();    final boolean isCancellation = wasCancelled();    for (Pair<DataSubscriber<T>, Executor> pair : mSubscribers) {      notifyDataSubscriber(pair.first, pair.second, isFailure, isCancellation);    }  }  private void notifyDataSubscriber(      final DataSubscriber<T> dataSubscriber,      final Executor executor,      final boolean isFailure,      final boolean isCancellation) {    executor.execute(        new Runnable() {          @Override          public void run() {            if (isFailure) {              dataSubscriber.onFailure(AbstractDataSource.this);            } else if (isCancellation) {              dataSubscriber.onCancellation(AbstractDataSource.this);            } else {              dataSubscriber.onNewResult(AbstractDataSource.this);            }          }        });  }

这里就是通知观察者的具体实现,成功的话,会回调dataSubscriber的onNewResult方法,这个DataSource是何时订阅的呢?需要回调setController那一步了,在submitRequest时:(AbstractDraweeController.java)

final DataSubscriber<T> dataSubscriber =      new BaseDataSubscriber<T>() {        @Override        public void onNewResultImpl(DataSource<T> dataSource) {          // isFinished must be obtained before image, otherwise we might set intermediate result          // as final image.          boolean isFinished = dataSource.isFinished();          float progress = dataSource.getProgress();          T image = dataSource.getResult();          if (image != null) {            onNewResultInternal(id, dataSource, image, progress, isFinished, wasImmediate);          } else if (isFinished) {            onFailureInternal(id, dataSource, new NullPointerException(), /* isFinished */ true);          }        }        @Override        public void onFailureImpl(DataSource<T> dataSource) {          onFailureInternal(id, dataSource, dataSource.getFailureCause(), /* isFinished */ true);        }        @Override        public void onProgressUpdate(DataSource<T> dataSource) {          boolean isFinished = dataSource.isFinished();          float progress = dataSource.getProgress();          onProgressUpdateInternal(id, dataSource, progress, isFinished);        }      };  mDataSource.subscribe(dataSubscriber, mUiThreadImmediateExecutor);

就是这里,我们知道BaseDataSubscriber是DataSubsciber的base实现,成功的话,会回调onNewResultImpl方法,我们注意下11行onNewResultInternal:

  private void onNewResultInternal(      String id,      DataSource<T> dataSource,      @Nullable T image,      float progress,      boolean isFinished,      boolean wasImmediate) {    .........//省略    try {      // set the new image      if (isFinished) {        logMessageAndImage("set_final_result @ onNewResult", image);        mDataSource = null;        mSettableDraweeHierarchy.setImage(drawable, 1f, wasImmediate);  //显示图片        getControllerListener().onFinalImageSet(id, getImageInfo(image), getAnimatable());        // IMPORTANT: do not execute any instance-specific code after this point      } else {        logMessageAndImage("set_intermediate_result @ onNewResult", image);        mSettableDraweeHierarchy.setImage(drawable, progress, wasImmediate);        getControllerListener().onIntermediateImageSet(id, getImageInfo(image));        // IMPORTANT: do not execute any instance-specific code after this point      }    } finally {      if (previousDrawable != null && previousDrawable != drawable) {        releaseDrawable(previousDrawable);      }      if (previousImage != null && previousImage != image) {        logMessageAndImage("release_previous_result @ onNewResult", previousImage);        releaseImage(previousImage);      }    }  }

第15行 mSettableDraweeHierarchy.setImage(drawable, 1f, wasImmediate);就是用于显示图片啦。
这样整体的流程就结束了,从setImageUri到图片显示,关于图片显示的逻辑之后再写。

0 0
原创粉丝点击