Fresco源码分析(一)

Fresco学习中文地址:Fresco中文学习

Fresco Javadoc地址:Javadoc

Fresco初始化分析:

在Application中加入:

Fresco.initialize(this);

请看我的注释:

/*
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

package com.facebook.drawee.backends.pipeline;

import *

/**
 * Fresco entry point.(总体入口点)
 *
 * 

You must initialize this class before use. The simplest way is to just do * {#code Fresco.initialize(Context)}. * (指明了一个简单例子) */ public class Fresco { private static PipelineDraweeControllerBuilderSupplier sDraweeControllerBuilderSupplier; //业务逻辑工厂 private Fresco() {} /** Initializes Fresco with the default config. */ public static void initialize(Context context) { ImagePipelineFactory.initialize(context); // 关系图片下载逻辑处理和缓存处理 initializeDrawee(context); } /** Initializes Fresco with the specified config. */ public static void initialize(Context context, ImagePipelineConfig imagePipelineConfig) { ImagePipelineFactory.initialize(imagePipelineConfig); // 关系图片下载逻辑处理和缓存处理 initializeDrawee(context); } private static void initializeDrawee(Context context) { sDraweeControllerBuilderSupplier = new PipelineDraweeControllerBuilderSupplier(context); SimpleDraweeView.initialize(sDraweeControllerBuilderSupplier); // 这个SimpleDraweeView是在布局中使用的代理Imageview,挂在一堆转换逻辑 } /** Gets the supplier of Fresco Drawee controller builders. */ public static PipelineDraweeControllerBuilderSupplier getDraweeControllerBuilderSupplier() { return sDraweeControllerBuilderSupplier; // 这货给外部使用,看需求而定 } /** Returns a new instance of Fresco Drawee controller builder. */ public static PipelineDraweeControllerBuilder newDraweeControllerBuilder() { return sDraweeControllerBuilderSupplier.get(); // 给外部需求所用,拿到一个新的业务逻辑工厂对象 } public static ImagePipelineFactory getImagePipelineFactory() { return ImagePipelineFactory.getInstance(); // 外部使用的管道类,这货检查是否初始化 } /** Gets the image pipeline instance. */ public static ImagePipeline getImagePipeline() { return getImagePipelineFactory().getImagePipeline();// 外部使用的管道类,这货检查是否初始化,没有给你个新的,工厂模式 } /** Shuts Fresco down. */ public static void shutDown() { //Application 退出调用,避免内存泄露 sDraweeControllerBuilderSupplier = null; SimpleDraweeView.shutDown(); ImagePipelineFactory.shutDown(); } }

初始化翻译就这样:

Fresco.initialize() ===> Fresco.initializeDrawee() ===> SimpleDraweeView.initialize();

请继续看我的注释:

/*
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

package com.facebook.drawee.view;

import *

/**
 * This view takes a uri as input and internally builds and sets a controller.(这个类就是挂载url和control准备)
 *
 * 

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. * (官方教育你,先初始化Fresco.initialize) */ public class SimpleDraweeView extends GenericDraweeView { // 这个继承有点深,慢慢来,最终爸爸肯定是ImageView,但每个继承做了深度定制 private static Supplier sDraweeControllerBuilderSupplier;// 这货就是前面初始化进来的业务逻辑提供者 /** Initializes {@link SimpleDraweeView} with supplier of Drawee controller builders. */ public static void initialize( // 初始化传值 Supplier draweeControllerBuilderSupplier) { sDraweeControllerBuilderSupplier = draweeControllerBuilderSupplier; } /** Shuts {@link SimpleDraweeView} down. */ public static void shutDown() { // 关闭 sDraweeControllerBuilderSupplier = null; } private SimpleDraweeControllerBuilder mSimpleDraweeControllerBuilder; // 真正的业务逻辑对象,从sDraweeControllerBuilderSupplier拿出 public SimpleDraweeView(Context context, GenericDraweeHierarchy hierarchy) { super(context, hierarchy); init(context, null); } public SimpleDraweeView(Context context) { super(context); init(context, null); } public SimpleDraweeView(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public SimpleDraweeView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public SimpleDraweeView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(context, attrs); } private void init(Context context, @Nullable AttributeSet attrs) { if (isInEditMode()) { // 来自view,是否控件可以编辑 return; } Preconditions.checkNotNull( sDraweeControllerBuilderSupplier, "SimpleDraweeView was not initialized!"); // 检查sDraweeControllerBuilderSupplier mSimpleDraweeControllerBuilder = sDraweeControllerBuilderSupplier.get(); // 拿到对应的业务逻辑(正常来说都是PipelineDraweeControllerBuilder,如果自己没有外部定制需求) // 拿布局属性,基本无用,可以是个默认图uri if (attrs != null) { TypedArray gdhAttrs = context.obtainStyledAttributes( attrs, R.styleable.SimpleDraweeView); try { if (gdhAttrs.hasValue(R.styleable.SimpleDraweeView_actualImageUri)) { setImageURI(Uri.parse(gdhAttrs.getString(R.styleable.SimpleDraweeView_actualImageUri)), null); } } finally { gdhAttrs.recycle(); } } } 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) { // 定制网络图片url setImageURI(uri, null); } /** * Displays an image given by the uri string. * * @param uriString uri string of the image */ public void setImageURI(@Nullable String uriString) { setImageURI(uriString, 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) { // builder模式建立DraweeController DraweeController controller = mSimpleDraweeControllerBuilder .setCallerContext(callerContext)// 这货如果没有指定,都是null,一直传到所有的生产者中 .setUri(uri) .setOldController(getController())// 这货首次是null .build(); setController(controller); } /** * Displays an image given by the uri string. * * @param uriString uri string of the image * @param callerContext caller context */ public void setImageURI(@Nullable String uriString, @Nullable Object callerContext) { // 多态 Uri uri = (uriString != null) ? Uri.parse(uriString) : null; setImageURI(uri, callerContext); } }

SimpleDraweeView 的继承先不看,控件处理而已,先看完关心request流程。

流程:SimpleDraweeView.setImageURI() ===> PipelineDraweeControllerBuilder.build(),然后SimpleDraweeView 再持有PipelineDraweeController这个对象

接着看注释,这个build类:

package com.facebook.drawee.backends.pipeline;

import *

/**
 * Concrete implementation of ImagePipeline Drawee controller builder. (业务逻辑实现类)
 * 

See {@link AbstractDraweeControllerBuilder} for more details. */ public class PipelineDraweeControllerBuilder extends AbstractDraweeControllerBuilder< PipelineDraweeControllerBuilder, ImageRequest, CloseableReference, ImageInfo> { // 很多实现在基类AbstractDraweeControllerBuilder完成,如果你需要定制自己DraweeController,继承这个基类 private final ImagePipeline mImagePipeline; // 各种缓存和策略,维护脏活的就是它 private final PipelineDraweeControllerFactory mPipelineDraweeControllerFactory;// 这货持有uiThread,用来回掉更新,配合ImagePipeline 完成请求 public PipelineDraweeControllerBuilder( Context context, PipelineDraweeControllerFactory pipelineDraweeControllerFactory, ImagePipeline imagePipeline, Set boundControllerListeners) { super(context, boundControllerListeners); mImagePipeline = imagePipeline; mPipelineDraweeControllerFactory = pipelineDraweeControllerFactory; } @Override public PipelineDraweeControllerBuilder setUri(Uri uri) { // 转换成一个ImageRequest return super.setImageRequest(ImageRequest.fromUri(uri)); } @Override public PipelineDraweeControllerBuilder setUri(@Nullable String uriString) { // 转换成一个ImageRequest return super.setImageRequest(ImageRequest.fromUri(uriString)); } // 这个函数来自SimpleDraweeView:setImageURI():PipelineDraweeControllerBuilder.build() @Override protected PipelineDraweeController obtainController() { // 父类会回掉,首次会走else,为了重复使用,把新数据更新到controller中 DraweeController oldController = getOldController(); PipelineDraweeController controller; if (oldController instanceof PipelineDraweeController) { controller = (PipelineDraweeController) oldController; controller.initialize( obtainDataSourceSupplier(), generateUniqueControllerId(), getCacheKey(), getCallerContext()); } else { controller = mPipelineDraweeControllerFactory.newController( obtainDataSourceSupplier(), generateUniqueControllerId(), getCacheKey(), getCallerContext()); } return controller; } private CacheKey getCacheKey() { // 根据imageRequest 拿到对应的Cache策略,这货从ImagePipeline 拿到Cache final ImageRequest imageRequest = getImageRequest(); final CacheKeyFactory cacheKeyFactory = mImagePipeline.getCacheKeyFactory(); CacheKey cacheKey = null; if (cacheKeyFactory != null && imageRequest != null) { if (imageRequest.getPostprocessor() != null) { cacheKey = cacheKeyFactory.getPostprocessedBitmapCacheKey( imageRequest, getCallerContext()); } else { cacheKey = cacheKeyFactory.getBitmapCacheKey( imageRequest, getCallerContext()); } } return cacheKey; } // 数据Bean,带有回掉数据接口(成功或者失败),利用执行ImagePipeline request @Override protected DataSource> getDataSourceForRequest( ImageRequest imageRequest, Object callerContext, boolean bitmapCacheOnly) { if (bitmapCacheOnly) { return mImagePipeline.fetchImageFromBitmapCache(imageRequest, callerContext); } else { return mImagePipeline.fetchDecodedImage(imageRequest, callerContext); } } ....... }

好了大致知道了Cache类和Executor类了,都来自ImagePipeline。
ImagePipeline 负责图片的获取和管理。图片可以来自远程服务器,本地文件,或者Content Provider,本地资源。压缩后的文件缓存在本地存储中,Bitmap数据缓存在内存中。
obtainController(),这个函数比较重要,构造了业务逻辑,有点像MVC,这里创建后生成回掉,给后面view,addWindow()后,收集WMS和IMS(WindowManagerService和InputeManagerService)产生的生命周期回掉或者输入事件绑定。

在5.0系统以下,Image Pipeline 使用 pinned purgeables 将Bitmap数据避开Java堆内存,存在ashmem中。这要求图片不使用时,要显式地释放内存。
SimpleDraweeView自动处理了这个释放过程,所以没有特殊情况,尽量使用SimpleDraweeView,在特殊的场合,如果有需要,也可以直接控制Image Pipeline。

Fresco源码分析(一)_第1张图片
Paste_Image.png

ImagePipeline介绍来自
关于ImagePipeline后面文章介绍里面策略和缓存详细,先看主request

那执行Requst代码在哪,在前面SimpleDraweeView.setImageURI()里面是执行

package com.facebook.drawee.backends.pipeline;

import *

/**
 * Drawee controller that bridges the image pipeline with {@link SettableDraweeHierarchy}. 

The * hierarchy's actual image is set to the image(s) obtained by the provided data source. The data * source is automatically obtained and closed based on attach / detach calls. */ public class PipelineDraweeController extends AbstractDraweeController, ImageInfo> { // Components private final Resources mResources; private final AnimatedDrawableFactory mAnimatedDrawableFactory; private @Nullable MemoryCache mMemoryCache; private static Experiment sExperiment; // 这货相当于一个对象锁 private CacheKey mCacheKey; // Constant state (non-final because controllers can be reused) private Supplier>> mDataSourceSupplier; public PipelineDraweeController( // 初始化和传值一堆,为了基类使用 Resources resources, DeferredReleaser deferredReleaser, AnimatedDrawableFactory animatedDrawableFactory, Executor uiThreadExecutor, MemoryCache memoryCache, Supplier>> dataSourceSupplier, String id, CacheKey cacheKey, Object callerContext) { super(deferredReleaser, uiThreadExecutor, id, callerContext); mResources = resources; mAnimatedDrawableFactory = animatedDrawableFactory; mMemoryCache = memoryCache; mCacheKey = cacheKey; init(dataSourceSupplier); } public void initialize( Supplier>> dataSourceSupplier, String id, CacheKey cacheKey, Object callerContext) { super.initialize(id, callerContext); init(dataSourceSupplier); mCacheKey = cacheKey; } private void init(Supplier>> dataSourceSupplier) { mDataSourceSupplier = dataSourceSupplier; } // 这个函数比较重要,利用DataSourceSupplier提供model接口数据接口(MVC模式) @Override protected DataSource> getDataSource() { // 更新数据的接口,有成功和失败 if (FLog.isLoggable(FLog.VERBOSE)) { FLog.v(TAG, "controller %x: getDataSource", System.identityHashCode(this)); } return mDataSourceSupplier.get(); } @Override protected Drawable createDrawable(CloseableReference image) {// 创建Drawable的策略回掉 Preconditions.checkState(CloseableReference.isValid(image)); CloseableImage closeableImage = image.get(); if (closeableImage instanceof CloseableStaticBitmap) { CloseableStaticBitmap closeableStaticBitmap = (CloseableStaticBitmap) closeableImage; Drawable bitmapDrawable = new BitmapDrawable( mResources, closeableStaticBitmap.getUnderlyingBitmap()); if (closeableStaticBitmap.getRotationAngle() == 0 || closeableStaticBitmap.getRotationAngle() == EncodedImage.UNKNOWN_ROTATION_ANGLE) { return bitmapDrawable; } else { return new OrientedDrawable(bitmapDrawable, closeableStaticBitmap.getRotationAngle()); } } else if (mAnimatedDrawableFactory != null) { return mAnimatedDrawableFactory.create(closeableImage); } else { throw new UnsupportedOperationException("Unrecognized image class: " + closeableImage); } } ....... @Override protected void releaseImage(@Nullable CloseableReference image) { // 释放引用策略 CloseableReference.closeSafely(image); } @Override protected void releaseDrawable(@Nullable Drawable drawable) { // 释放引用策略 if (drawable instanceof DrawableWithCaches) { ((DrawableWithCaches) drawable).dropCaches(); } } @Override protected CloseableReference getCachedImage() { // 关闭引用策略 if (!getExperiment().mIsFastCheckEnabled) { return null; } if (mMemoryCache == null || mCacheKey == null) { return null; } // We get the CacheKey CloseableReference closeableImage = mMemoryCache.get(mCacheKey); if (closeableImage != null && !closeableImage.get().getQualityInfo().isOfFullQuality()) { closeableImage.close(); return null; } return closeableImage; } /** * @return The Experiment object */ protected static Experiment getExperiment() { if (sExperiment == null) { sExperiment = new Experiment(); } return sExperiment; } protected static class Experiment { // 检查类 private boolean mIsFastCheckEnabled; public Experiment setFastCheckEnabled(final boolean fastCheckEnabled) { mIsFastCheckEnabled = fastCheckEnabled; return this; } } }

上面只是实力类,真正调用在基类, 比较重要的就是getDataSource()和createDrawable()的实现了,其它都是释放资源和回收,后面再讲这个资源回收和回掉过程

接下来看基类指明干活


package com.facebook.drawee.controller;

import *

/**
 * Abstract Drawee controller that implements common functionality
 * regardless of the backend used to fetch the image.
 *
 * All methods should be called on the main UI thread.
 *
 */
@NotThreadSafe
public abstract class AbstractDraweeController implements
    DraweeController,
    DeferredReleaser.Releasable,
    GestureDetector.ClickListener {

  /**
   * This class is used to allow an optimization of not creating a ForwardingControllerListener
   * when there is only a single controller listener.
   * 这货也比较重要,但尼玛你没有定制自己controllistener,默认为null,没有什么卵用
   */
  private static class InternalForwardingListener extends ForwardingControllerListener { 
    public static  InternalForwardingListener createInternal(
        ControllerListener listener1,
        ControllerListener listener2) {
      InternalForwardingListener forwarder = new InternalForwardingListener();
      forwarder.addListener(listener1);
      forwarder.addListener(listener2);
      return forwarder;
    }
  }

  // Components
  private final DraweeEventTracker mEventTracker = DraweeEventTracker.newInstance(); // 日志追踪
  private final DeferredReleaser mDeferredReleaser; // 赖加载,延迟安排任务
  private final Executor mUiThreadImmediateExecutor; // ui线程从PipelineDraweeControllerBuilder :PipelineDraweeControllerFactory 来的

  // Optional components
  private @Nullable RetryManager mRetryManager; // 重试机制
  private @Nullable GestureDetector mGestureDetector; // 手势
  private @Nullable ControllerListener mControllerListener; // 业务逻辑回掉监听

  // Hierarchy
  private @Nullable SettableDraweeHierarchy mSettableDraweeHierarchy; // view对象树, 用于组织和维护最终绘制和呈现的 Drawable 对象
  private @Nullable Drawable mControllerOverlay; // view对象

  // Constant state (non-final because controllers can be reused)
  private String mId;
  private Object mCallerContext;

  // Mutable state
  private boolean mIsAttached; // 是否view添加到window上
  private boolean mIsRequestSubmitted; // 是否已经开始request
  private boolean mHasFetchFailed;// 当前request更新失败flag
  private boolean mRetainImageOnFailure;// 设置是否显示最新的可用的图片(默认图),在失败的时候
  private @Nullable String mContentDescription; // 描述
  private @Nullable DataSource mDataSource; // 子类data策略
  private @Nullable T mFetchedImage; // 获取到当前image
  private @Nullable Drawable mDrawable; // 图片资源

  public AbstractDraweeController(
      DeferredReleaser deferredReleaser,
      Executor uiThreadImmediateExecutor,
      String id,
      Object callerContext) {
    mDeferredReleaser = deferredReleaser;
    mUiThreadImmediateExecutor = uiThreadImmediateExecutor;
    init(id, callerContext, true);
  }

  protected void initialize(String id, Object callerContext) {
    init(id, callerContext, false);
  }

  private void init(String id, Object callerContext, boolean justConstructed) {
    mEventTracker.recordEvent(Event.ON_INIT_CONTROLLER);
    // cancel deferred release
    if (!justConstructed && mDeferredReleaser != null) {
      mDeferredReleaser.cancelDeferredRelease(this);
    }
    // reinitialize mutable state (fetch state)
    mIsAttached = false;
    releaseFetch();
    mRetainImageOnFailure = false;
    // reinitialize optional components
    if (mRetryManager != null) {
      mRetryManager.init();
    }
    if (mGestureDetector != null) {
      mGestureDetector.init();
      mGestureDetector.setClickListener(this);
    }
    if (mControllerListener instanceof InternalForwardingListener) {
      ((InternalForwardingListener) mControllerListener).clearListeners();
    } else {
      mControllerListener = null;
    }
    // clear hierarchy and controller overlay
    if (mSettableDraweeHierarchy != null) {
      mSettableDraweeHierarchy.reset();
      mSettableDraweeHierarchy.setControllerOverlay(null);
      mSettableDraweeHierarchy = null;
    }
    mControllerOverlay = null;
    // reinitialize constant state
    if (FLog.isLoggable(FLog.VERBOSE)) {
      FLog.v(TAG, "controller %x %s -> %s: initialize", System.identityHashCode(this), mId, id);
    }
    mId = id;
    mCallerContext = callerContext;
  }

  @Override
  public void release() {
    mEventTracker.recordEvent(Event.ON_RELEASE_CONTROLLER);
    if (mRetryManager != null) {
      mRetryManager.reset();
    }
    if (mGestureDetector != null) {
      mGestureDetector.reset();
    }
    if (mSettableDraweeHierarchy != null) {
      mSettableDraweeHierarchy.reset();
    }
    releaseFetch();
  }

  private void releaseFetch() { // 释放hold的image和data,为request做准备
    boolean wasRequestSubmitted = mIsRequestSubmitted;
    mIsRequestSubmitted = false;
    mHasFetchFailed = false;
    if (mDataSource != null) {
      mDataSource.close();
      mDataSource = null;
    }
    if (mDrawable != null) {
      releaseDrawable(mDrawable);
    }
    if (mContentDescription != null) {
      mContentDescription = null;
    }
    mDrawable = null;
    if (mFetchedImage != null) {
      logMessageAndImage("release", mFetchedImage);
      releaseImage(mFetchedImage);
      mFetchedImage = null;
    }
    if (wasRequestSubmitted) {
      getControllerListener().onRelease(mId);
    }
  }

  public Object getCallerContext() { // 默认情况都是null,基本无卵用,如果你有特殊要求,这个上下文能起到很大重要,如,日志追踪
    return mCallerContext;
  }

  protected @Nullable RetryManager getRetryManager() { // 重试机制
    return mRetryManager;
  }

      .......

  /** Gets gesture detector. */
  protected @Nullable GestureDetector getGestureDetector() {
    return mGestureDetector;
  }

  /** Sets gesture detector. */
  protected void setGestureDetector(@Nullable GestureDetector gestureDetector) {
    mGestureDetector = gestureDetector;
    if (mGestureDetector != null) {
      mGestureDetector.setClickListener(this);
    }
  }

// 这货有意思了,这货给你个flag,需要set进来,作用是你下载完后,失败需要重新下载标志
  protected void setRetainImageOnFailure(boolean enabled) {
    mRetainImageOnFailure = enabled;
  }

      .......

 // 基本无用,默认是null,为了完成你自己定制的回掉监听设置
  /** Adds controller listener. */
  public void addControllerListener(ControllerListener controllerListener) {
    Preconditions.checkNotNull(controllerListener);
    if (mControllerListener instanceof InternalForwardingListener) {
      ((InternalForwardingListener) mControllerListener).addListener(controllerListener);
      return;
    }
    if (mControllerListener != null) {
      mControllerListener = InternalForwardingListener.createInternal(
          mControllerListener,
          controllerListener);
      return;
    }
    // Listener only receives , it never produces one.
    // That means if it can accept , it can very well accept .
    mControllerListener = (ControllerListener) controllerListener;
  }

      .......

  /** Gets controller listener for internal use. */
  protected ControllerListener getControllerListener() {
    if (mControllerListener == null) {
      return BaseControllerListener.getNoOpListener();
    }
    return mControllerListener;
  }

  /** Gets the hierarchy */
  @Override
  public @Nullable
  DraweeHierarchy getHierarchy() {
    return mSettableDraweeHierarchy;
  }

  // 这函数比较屌,维护view树,以后再讲
  @Override
  public void setHierarchy(@Nullable DraweeHierarchy hierarchy) {
    if (FLog.isLoggable(FLog.VERBOSE)) {
      FLog.v(
          TAG,
          "controller %x %s: setHierarchy: %s",
          System.identityHashCode(this),
          mId,
          hierarchy);
    }
    mEventTracker.recordEvent(
        (hierarchy != null) ? Event.ON_SET_HIERARCHY : Event.ON_CLEAR_HIERARCHY);
    // force release in case request was submitted
    if (mIsRequestSubmitted) {
      mDeferredReleaser.cancelDeferredRelease(this);
      release();
    }
    // clear the existing hierarchy
    if (mSettableDraweeHierarchy != null) {
      mSettableDraweeHierarchy.setControllerOverlay(null);
      mSettableDraweeHierarchy = null;
    }
    // set the new hierarchy
    if (hierarchy != null) {
      Preconditions.checkArgument(hierarchy instanceof SettableDraweeHierarchy);
      mSettableDraweeHierarchy = (SettableDraweeHierarchy) hierarchy;
      mSettableDraweeHierarchy.setControllerOverlay(mControllerOverlay);
    }
  }

  /** Sets the controller overlay */
  protected void setControllerOverlay(@Nullable Drawable controllerOverlay) {
    mControllerOverlay = controllerOverlay;
    if (mSettableDraweeHierarchy != null) {
      mSettableDraweeHierarchy.setControllerOverlay(mControllerOverlay);
    }
  }

  /** Gets the controller overlay */
  protected @Nullable Drawable getControllerOverlay() {
    return mControllerOverlay;
  }

  @Override
  public void onAttach() { // 回调
    if (FLog.isLoggable(FLog.VERBOSE)) {
      FLog.v(
          TAG,
          "controller %x %s: onAttach: %s",
          System.identityHashCode(this),
          mId,
          mIsRequestSubmitted ? "request already submitted" : "request needs submit");
    }
    mEventTracker.recordEvent(Event.ON_ATTACH_CONTROLLER);
    Preconditions.checkNotNull(mSettableDraweeHierarchy);
    mDeferredReleaser.cancelDeferredRelease(this);
    mIsAttached = true;
    if (!mIsRequestSubmitted) {
      submitRequest();
    }
  }

  @Override
  public void onDetach() { // 回调
    if (FLog.isLoggable(FLog.VERBOSE)) {
      FLog.v(TAG, "controller %x %s: onDetach", System.identityHashCode(this), mId);
    }
    mEventTracker.recordEvent(Event.ON_DETACH_CONTROLLER);
    mIsAttached = false;
    mDeferredReleaser.scheduleDeferredRelease(this);
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) { // 回调
    if (FLog.isLoggable(FLog.VERBOSE)) {
      FLog.v(TAG, "controller %x %s: onTouchEvent %s", System.identityHashCode(this), mId, event);
    }
    if (mGestureDetector == null) {
      return false;
    }
    if (mGestureDetector.isCapturingGesture() || shouldHandleGesture()) {
      mGestureDetector.onTouchEvent(event);
      return true;
    }
    return false;
  }

  /** Returns whether the gesture should be handled by the controller */
  protected boolean shouldHandleGesture() {
    return shouldRetryOnTap();
  }

  private boolean shouldRetryOnTap() {
    // We should only handle touch event if we are expecting some gesture.
    // For example, we expect click when fetch fails and tap-to-retry is enabled.
    return mHasFetchFailed && mRetryManager != null && mRetryManager.shouldRetryOnTap(); // shouldRetryOnTap 判断是否超过重新的最大值(MAX:4次)
  }

  @Override
  public boolean onClick() {// 回调
    if (FLog.isLoggable(FLog.VERBOSE)) {
      FLog.v(TAG, "controller %x %s: onClick", System.identityHashCode(this), mId);
    }
    if (shouldRetryOnTap()) { // mRetryManager去通知重新request准备
      mRetryManager.notifyTapToRetry();
      mSettableDraweeHierarchy.reset();
      submitRequest();
      return true;
    }
    return false;
  }

  protected void submitRequest() { // 这货就是干活的
    final T closeableImage = getCachedImage(); // 拿到子类的Cache图片
    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); // 给监听器去干活,一个id一个坑
    mSettableDraweeHierarchy.setProgress(0, true);// 对象树准备
    mIsRequestSubmitted = true;// 已经提交
    mHasFetchFailed = false;// 重置
    mDataSource = getDataSource(); // 获取子类data策略
    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 dataSubscriber =
        new BaseDataSubscriber() {
          @Override
          public void onNewResultImpl(DataSource 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 dataSource) {
            onFailureInternal(id, dataSource, dataSource.getFailureCause(), /* isFinished */ true);
          }
          @Override
          public void onProgressUpdate(DataSource dataSource) {
            boolean isFinished = dataSource.isFinished();
            float progress = dataSource.getProgress();
            onProgressUpdateInternal(id, dataSource, progress, isFinished);
          }
        };
    mDataSource.subscribe(dataSubscriber, mUiThreadImmediateExecutor); // 在ui线程订阅,开始刷新
  }

  private void onNewResultInternal( // 成功
      String id,
      DataSource dataSource,
      @Nullable T image,
      float progress,
      boolean isFinished,
      boolean wasImmediate) {
    // ignore late callbacks (data source that returned the new result is not the one we expected)
    if (!isExpectedDataSource(id, dataSource)) { // 略过老data
      logMessageAndImage("ignore_old_datasource @ onNewResult", image);
      releaseImage(image);
      dataSource.close();
      return;
    }
    mEventTracker.recordEvent( // 日志追踪
        isFinished ? Event.ON_DATASOURCE_RESULT : Event.ON_DATASOURCE_RESULT_INT);
    // create drawable
    Drawable drawable;
    try {
      drawable = createDrawable(image); //调用子类策略创建drawable 
    } catch (Exception exception) { // 失败打印和释放资源
      logMessageAndImage("drawable_failed @ onNewResult", image);
      releaseImage(image);
      onFailureInternal(id, dataSource, exception, isFinished);
      return;
    }
    T previousImage = mFetchedImage; // 完成新老数据交换
    Drawable previousDrawable = mDrawable;
    mFetchedImage = image; // 给hold的当前image进行策略释放
    mDrawable = drawable;
    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);
      }
    }
  }

  private void onFailureInternal( // 更新失败数据
      String id,
      DataSource dataSource,
      Throwable throwable,
      boolean isFinished) {
    // ignore late callbacks (data source that failed is not the one we expected)
    if (!isExpectedDataSource(id, dataSource)) { // 判断是否是自己感兴趣的data
      logMessageAndFailure("ignore_old_datasource @ onFailure", throwable);
      dataSource.close();
      return;
    }
    mEventTracker.recordEvent( // 日志追踪
        isFinished ? Event.ON_DATASOURCE_FAILURE : Event.ON_DATASOURCE_FAILURE_INT);
    // fail only if the data source is finished
    if (isFinished) { //刷新失败流程
      logMessageAndFailure("final_failed @ onFailure", throwable);
      mDataSource = null;
      mHasFetchFailed = true;
      // Set the previously available image if available.
      if (mRetainImageOnFailure && mDrawable != null) {
        mSettableDraweeHierarchy.setImage(mDrawable, 1f, true);
      } else if (shouldRetryOnTap()) {
        mSettableDraweeHierarchy.setRetry(throwable);
      } else {
        mSettableDraweeHierarchy.setFailure(throwable);
      }
      getControllerListener().onFailure(mId, throwable);
      // IMPORTANT: do not execute any instance-specific code after this point
    } else {
      logMessageAndFailure("intermediate_failed @ onFailure", throwable);
      getControllerListener().onIntermediateImageFailed(mId, throwable);
      // IMPORTANT: do not execute any instance-specific code after this point
    }
  }

  private void onProgressUpdateInternal( // 更新实时数据
      String id,
      DataSource dataSource,
      float progress,
      boolean isFinished) {
    // ignore late callbacks (data source that failed is not the one we expected)
    if (!isExpectedDataSource(id, dataSource)) {
      logMessageAndFailure("ignore_old_datasource @ onProgress", null);
      dataSource.close();
      return;
    }
    if (!isFinished) {
      mSettableDraweeHierarchy.setProgress(progress, false);
    }
  }

  private boolean isExpectedDataSource(String id, DataSource dataSource) { // 判断当前提交状态的dataSource 释放为新的,持有id老dataSource 不再感兴趣
    if (dataSource == null && mDataSource == null) {
      // DataSource is null when we use directly the Bitmap from the MemoryCache. In this case
      // we don't have to close the DataSource.
      return true;
    }
    // There are several situations in which an old data source might return a result that we are no
    // longer interested in. To verify that the result is indeed expected, we check several things:
    return id.equals(mId) && dataSource == mDataSource && mIsRequestSubmitted;
  }

     ........

  @Override
  public @Nullable Animatable getAnimatable() {
    return (mDrawable instanceof Animatable) ? (Animatable) mDrawable : null;
  }

 // 下面都是回掉子类接口 PipelineDraweeController

  protected abstract DataSource getDataSource();

  protected abstract Drawable createDrawable(T image);

  protected abstract @Nullable INFO getImageInfo(T image);

  protected String getImageClass(@Nullable T image) {
    return (image != null) ? image.getClass().getSimpleName() : "";
  }

  protected int getImageHash(@Nullable T image) {
    return System.identityHashCode(image);
  }

  protected abstract void releaseImage(@Nullable T image);

  protected abstract void releaseDrawable(@Nullable Drawable drawable);

     ........

}

属性:SettableDraweeHierarchy 你可以认为这货就是你的drawable的修饰类所需要维护的树形结构,相当于drawable是衣服的话,DraweeHierarchy就是衣服上的线条结构和底色配色,和XML中布局默认属性差不多

这个类比较长,所有request是从attach开始submit,onDetach停止和释放资源维护。

attach和onDetach事件来自于DraweeHierarchy中toplevel,Drawable的DraweeHold,它实现了监听和派发回掉

好了你大致也看懂了submit这个函数中,先准备一些flag,然后给Listener去实现submit,然后自己订阅回掉在ui线程,开始刷新界面。

这个大多数人都有个误区,认为Listener是实现提交请求,其实不是,这货只是监听回调,真正在跑网络数据得是这个订阅得datasrouce,而这个datasrouce来自getDataSource(),这个来自AbstractDraweeControllerBuilder:getDataSourceSupplierForRequest(),一路追踪最后来自PipelineDraweeControllerBuilder:getDataSourceForRequest(),好了这个主线来了,ImagePipeline要开始干活了,往上面翻,自己再总结理解下。

接着看:Fresco源码分析(二)

你可能感兴趣的:(Fresco源码分析(一))