接上文《Fresco圖片框架實(shí)現(xiàn)原理(一)》文末
private static void initializeDrawee(
Context context,
@Nullable DraweeConfig draweeConfig) {
sDraweeControllerBuilderSupplier =
new PipelineDraweeControllerBuilderSupplier(context, draweeConfig);
SimpleDraweeView.initialize(sDraweeControllerBuilderSupplier); }
在研究正真的PipelineDraweeController之前,先來(lái)看看PipelineDraweeControllerBuilder在Fresco中的構(gòu)造原理和過(guò)程
從上面的函數(shù)我們一個(gè)一個(gè)往里面點(diǎn)

image.png
PipelineDraweeControllerBuilderSupplier是一個(gè)提供者模式,主要是為了構(gòu)造PipelineDraweeControllerBuilder類(lèi)
圖像管道Drawee contrller builder的具體實(shí)現(xiàn)類(lèi)

PipelineDraweeControllerBuilder.png

AbstractDraweeControllerBuilder.png

SimpleDraweeControllerBuilder接口.png
這下繼承關(guān)系清除了:

繼承關(guān)系圖.png
SimpleDraweeControllerBuilder
/**
* Interface for simple Drawee controller builders.
*/
simple Drawee controller builders的接口
public interface SimpleDraweeControllerBuilder {
/** Sets the caller context. */
設(shè)置調(diào)用者上下文
SimpleDraweeControllerBuilder setCallerContext(Object callerContext);
/** Sets the uri. */
設(shè)置圖像Uri
SimpleDraweeControllerBuilder setUri(Uri uri);
/** Sets the uri from a string. */
設(shè)置圖像Uri
SimpleDraweeControllerBuilder setUri(@Nullable String uriString);
/** Sets the old controller to be reused if possible. */
如果有可能,設(shè)置舊的controller 用以重用
SimpleDraweeControllerBuilder setOldController(@Nullable DraweeController oldController);
/** Builds the specified controller. */
構(gòu)建具體的DraweeController
DraweeController build();
}
AbstractDraweeControllerBuilder 源碼
/**
* Base implementation for Drawee controller builders.
*/
public abstract class AbstractDraweeControllerBuilder <
BUILDER extends AbstractDraweeControllerBuilder<BUILDER, REQUEST, IMAGE, INFO>,
REQUEST,
IMAGE,
INFO>
implements SimpleDraweeControllerBuilder {
private static final ControllerListener<Object> sAutoPlayAnimationsListener =
new BaseControllerListener<Object>() {
@Override
public void onFinalImageSet(String id, @Nullable Object info, @Nullable Animatable anim) {
if (anim != null) {
anim.start();
}
}
};
private static final NullPointerException NO_REQUEST_EXCEPTION =
new NullPointerException("No image request was specified!");
// components
private final Context mContext;
private final Set<ControllerListener> mBoundControllerListeners;
// builder parameters
private @Nullable Object mCallerContext;
圖片請(qǐng)求 ImageRequest
private @Nullable REQUEST mImageRequest;
底分辨率圖片請(qǐng)求
private @Nullable REQUEST mLowResImageRequest;
多圖片請(qǐng)求
private @Nullable REQUEST[] mMultiImageRequests;
private boolean mTryCacheOnlyFirst;
數(shù)據(jù)源提供者
private @Nullable Supplier<DataSource<IMAGE>> mDataSourceSupplier;
private @Nullable ControllerListener<? super INFO> mControllerListener;
private @Nullable ControllerViewportVisibilityListener mControllerViewportVisibilityListener;
是否可點(diǎn)擊重試
private boolean mTapToRetryEnabled;
是否需要自動(dòng)播放動(dòng)畫(huà)
private boolean mAutoPlayAnimations;
private boolean mRetainImageOnFailure;
private String mContentDescription;
// old controller to reuse
這個(gè)變量重要 重用的DraweeController ,其具體的對(duì)象,就給子類(lèi)去構(gòu)建
private @Nullable DraweeController mOldController;
private static final AtomicLong sIdCounter = new AtomicLong();
protected AbstractDraweeControllerBuilder(
Context context,
Set<ControllerListener> boundControllerListeners) {
mContext = context;
mBoundControllerListeners = boundControllerListeners;
init();
}
/** Initializes this builder. */
private void init() {
mCallerContext = null;
mImageRequest = null;
mLowResImageRequest = null;
mMultiImageRequests = null;
mTryCacheOnlyFirst = true;
mControllerListener = null;
mControllerViewportVisibilityListener = null;
默認(rèn)false
mTapToRetryEnabled = false;
默認(rèn)不自動(dòng)播放
mAutoPlayAnimations = false;
mOldController = null;
mContentDescription = null;
}
....其他方法
/** Builds a regular controller. */
構(gòu)建一個(gè)常規(guī)的controller
protected AbstractDraweeController buildController() {
AbstractDraweeController controller = obtainController();
controller.setRetainImageOnFailure(getRetainImageOnFailure());
controller.setContentDescription(getContentDescription());
controller.setControllerViewportVisibilityListener(getControllerViewportVisibilityListener());
maybeBuildAndSetRetryManager(controller);
maybeAttachListeners(controller);
return controller;
}
/** Concrete builder classes should override this method to return a new controller. */
這個(gè)抽象類(lèi)的唯一抽象方法,又子類(lèi)去實(shí)現(xiàn)構(gòu)造具體的類(lèi)
protected abstract AbstractDraweeController obtainController();
...其他方法
AbstractDraweeControllerBuilder 的作用其實(shí)就是提供DraweeControllerBuilder所需要的所有成員變量,然后具體的變量值交給子類(lèi)PipelineDraweeControllerBuilder去獲取實(shí)現(xiàn),并設(shè)置這些成員變量
PipelineDraweeControllerBuilder源碼:
/**
* Concrete implementation of ImagePipeline Drawee controller builder.
* <p/> See {@link AbstractDraweeControllerBuilder} for more details.
*/
ImagePipeline Drawee controller builder.的具體實(shí)現(xiàn)
public class PipelineDraweeControllerBuilder extends AbstractDraweeControllerBuilder<
PipelineDraweeControllerBuilder,
ImageRequest,
CloseableReference<CloseableImage>,
ImageInfo> {
重要的成員變量圖像管道,final類(lèi)型,初始化一遍不在變化,上篇文章中提到可以從ImagePipelineFactory中獲取
private final ImagePipeline mImagePipeline;
重要的成員變量 PipelineDraweeControllerFactory是PipelineDraweeController工廠(chǎng)
private final PipelineDraweeControllerFactory mPipelineDraweeControllerFactory;
@Nullable
private ImmutableList<DrawableFactory> mCustomDrawableFactories;
public PipelineDraweeControllerBuilder(
Context context,
PipelineDraweeControllerFactory pipelineDraweeControllerFactory,
ImagePipeline imagePipeline,
Set<ControllerListener> boundControllerListeners) {
super(context, boundControllerListeners);
mImagePipeline = imagePipeline;
mPipelineDraweeControllerFactory = pipelineDraweeControllerFactory;
}
@Override
public PipelineDraweeControllerBuilder setUri(@Nullable Uri uri) {
if (uri == null) {
return super.setImageRequest(null);
}
設(shè)置圖片Uri的的本質(zhì)是: 用此Uri構(gòu)建圖像請(qǐng)求ImageRequest,實(shí)際上Fresco加載圖片,都是構(gòu)造ImageRequest
ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(uri)
.setRotationOptions(RotationOptions.autoRotateAtRenderTime())
.build();
return super.setImageRequest(imageRequest);
}
@Override
public PipelineDraweeControllerBuilder setUri(@Nullable String uriString) {
if (uriString == null || uriString.isEmpty()) {
return super.setImageRequest(ImageRequest.fromUri(uriString));
}
return setUri(Uri.parse(uriString));
}
...其他方法
父級(jí)抽象類(lèi)的抽象方法,重要方法 obtainController。
@Override
protected PipelineDraweeController obtainController() {
先獲取之前設(shè)置的OldController
DraweeController oldController = getOldController();
PipelineDraweeController controller;
if (oldController instanceof PipelineDraweeController) {
如果oldController 是PipelineDraweeController的實(shí)例 ,就在從controller的實(shí)例上修改一些需要的值,不用再實(shí)例化一個(gè)controller
controller = (PipelineDraweeController) oldController;
controller.initialize(
obtainDataSourceSupplier(),
generateUniqueControllerId(),
getCacheKey(),
getCallerContext(),
mCustomDrawableFactories);
} else {
如果oldcontroller ==null 使用PipelineDraweeControllerFactory重新生成一個(gè)新的controller
controller = mPipelineDraweeControllerFactory.newController(
obtainDataSourceSupplier(),
generateUniqueControllerId(),
getCacheKey(),
getCallerContext(),
mCustomDrawableFactories);
}
return controller;
}
...其他方法
}
這個(gè)類(lèi)主要是為了設(shè)置一些builder所需要的值,并且構(gòu)造除樂(lè)具體的controller。PipelineDraweeController的實(shí)例
PipelineDraweeController這個(gè)類(lèi)是真正的DraweeController,這個(gè)下一章在分析。
PipelineDraweeControllerFactory是PipelineDraweeController的工廠(chǎng)類(lèi)。用于常見(jiàn)controller實(shí)例。
/**
* Default implementation of {@link PipelineDraweeControllerFactory}.
*/
public class PipelineDraweeControllerFactory {
private Resources mResources;
private DeferredReleaser mDeferredReleaser;
private DrawableFactory mAnimatedDrawableFactory;
private Executor mUiThreadExecutor;
private MemoryCache<CacheKey, CloseableImage> mMemoryCache;
@Nullable
private ImmutableList<DrawableFactory> mDrawableFactories;
@Nullable
private Supplier<Boolean> mDebugOverlayEnabledSupplier;
public void init(
Resources resources,
DeferredReleaser deferredReleaser,
DrawableFactory animatedDrawableFactory,
Executor uiThreadExecutor,
MemoryCache<CacheKey, CloseableImage> memoryCache,
@Nullable ImmutableList<DrawableFactory> drawableFactories,
@Nullable Supplier<Boolean> debugOverlayEnabledSupplier) {
mResources = resources;
mDeferredReleaser = deferredReleaser;
mAnimatedDrawableFactory = animatedDrawableFactory;
mUiThreadExecutor = uiThreadExecutor;
mMemoryCache = memoryCache;
mDrawableFactories = drawableFactories;
mDebugOverlayEnabledSupplier = debugOverlayEnabledSupplier;
}
public PipelineDraweeController newController(
Supplier<DataSource<CloseableReference<CloseableImage>>> dataSourceSupplier,
String id,
CacheKey cacheKey,
Object callerContext) {
return newController(dataSourceSupplier, id, cacheKey, callerContext, null);
}
public PipelineDraweeController newController(
Supplier<DataSource<CloseableReference<CloseableImage>>> dataSourceSupplier,
String id,
CacheKey cacheKey,
Object callerContext,
@Nullable ImmutableList<DrawableFactory> customDrawableFactories) {
Preconditions.checkState(mResources != null, "init() not called");
// Field values passed as arguments so that any subclass of PipelineDraweeControllerFactory
// can simply override internalCreateController() and return a custom Drawee controller
PipelineDraweeController controller = internalCreateController(
mResources,
mDeferredReleaser,
mAnimatedDrawableFactory,
mUiThreadExecutor,
mMemoryCache,
mDrawableFactories,
customDrawableFactories,
dataSourceSupplier,
id,
cacheKey,
callerContext);
if (mDebugOverlayEnabledSupplier != null) {
controller.setDrawDebugOverlay(mDebugOverlayEnabledSupplier.get());
}
return controller;
}
內(nèi)部創(chuàng)建PipelineDraweeController ,創(chuàng)建一個(gè)controller需要這么多參數(shù),所以需要上面講的重用controller的實(shí)例,只改變其中的幾個(gè)成員變量值就行了。
protected PipelineDraweeController internalCreateController(
Resources resources,
DeferredReleaser deferredReleaser,
DrawableFactory animatedDrawableFactory,
Executor uiThreadExecutor,
MemoryCache<CacheKey, CloseableImage> memoryCache,
@Nullable ImmutableList<DrawableFactory> globalDrawableFactories,
@Nullable ImmutableList<DrawableFactory> customDrawableFactories,
Supplier<DataSource<CloseableReference<CloseableImage>>> dataSourceSupplier,
String id,
CacheKey cacheKey,
Object callerContext) {
PipelineDraweeController controller = new PipelineDraweeController(
resources,
deferredReleaser,
animatedDrawableFactory,
uiThreadExecutor,
memoryCache,
dataSourceSupplier,
id,
cacheKey,
callerContext,
globalDrawableFactories);
controller.setCustomDrawableFactories(customDrawableFactories);
return controller;
}
}