Android图片加载框架Fresco分析(三)

Fresco的Controller层设计

经过之前的分析,已经知道DraweeView的显示是需要controller层与hierarchy层接洽的。

每个view都有一个controller来控制。我们还是从源码来分析一下。

上次说道,SimpleDraweeView需要Fresco类在初始化方法中设置一个controller。其实这个controller便是PipelineDraweeControllerBuilderSupplier类提供的对象。

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

以上这些都是针对SimpleDraweeView由Fresco设置默认Controller,并无法自己定义。如果用户非要自己定义该怎么办呢?开发者也给我们提供了一个方法,这个方法也是在Fresco这个类中的newDraweeControllerBuilder()方法。我们先说fresco是如何使用自定义controller来协调View和Model层的。而且默认的配置也是facebook所推荐使用的。

上图的逻辑主要是controller层的一些设置,还有一些其他属性和方法也并没有全部列出。但是可以看得出来Fresco使用的是构建者模式。从代码中一层一层来看。

Fresco在init的时候给SimpleDraweeView初始化了一个静态成员变量sDraweeControllerBuilderSupplier,而之后每个SimpleDraweeView对象的controller就是从这个里面得到的。Fresco初始化的这个Supplier其实是提供一个Builder,Builder可以用来构造controller。Supplier只是作为一个泛型,将Builder提供出来。

//Fresco类中对SimpleDraweeView初始化
sDraweeControllerBuilderSupplier = new PipelineDraweeControllerBuilderSupplier(context);
SimpleDraweeView.initialize(sDraweeControllerBuilderSupplier);

下面需要看一下PipelineDraweeControllerBuilderSupplier类的实现。PipelineDraweeControllerBuilderSupplier类中有个主要的构造函数。和实现了Supplier接口后的get方法。

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

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

这里的get方法很明显会返回一个PipelineDraweeControllerBuilder,这个也就是SimpleDraweeView中setImageURI时需要使用的

//SimpleDraweeView类中的代码段
  public void setImageURI(Uri uri, @Nullable Object callerContext) {
    DraweeController controller = mSimpleDraweeControllerBuilder
    .setCallerContext(callerContext)
    .setUri(uri)
    .setOldController(getController())
    .build();
    setController(controller);
  }

上段代码中的mSimpleDraweeControllerBuilder便是之前get方法中new出来的PipelineDraweeControllerBuilder。

PipelineDraweeControllerBuilder继承自AbstractDraweeControllerBuilder,这个类是所有ControllerBuilder的基础实现。而AbstractDraweeControllerBuilder又实现了SimpleDraweeControllerBuilder接口的方法。

在AbstractDraweeControllerBuilder实现的build()方法中又调用了buildController()方法,生成AbstractDraweeController对象并返回。由此便得到了真正的controller对象。

看一下AbstractDraweeControllerBuilder中的重要方法:

  @Override
  public AbstractDraweeController build() {
       validate();
    ...
    return buildController();
  }
  protected AbstractDraweeController buildController() {
    AbstractDraweeController controller = obtainController();
    maybeBuildAndSetRetryManager(controller);
    maybeAttachListeners(controller);
    return controller;
  }
//需要子类其实现此方法
protected abstract AbstractDraweeController obtainController();

我们在使用的时候也可以根据自己的需要去构造这个builder,设置相应的属性。在看一下SimpleDraweeControllerBuilder类的源码:

public interface SimpleDraweeControllerBuilder {
  /** Sets the caller context. */
  public SimpleDraweeControllerBuilder setCallerContext(Object callerContext);
  /** Sets the uri. */
  public SimpleDraweeControllerBuilder setUri(Uri uri);
  /** Sets the old controller to be reused if possible. */
  public SimpleDraweeControllerBuilder setOldController(@Nullable DraweeController oldController);
  /** Builds the specified controller. */
  public DraweeController build();
}

以上的分析便是supplier,builder,controller之间的继承和连接关系。