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之间的继承和连接关系。