接上文《Fresco圖片框架實現(xiàn)原理(一)》文末
private static void initializeDrawee(
Context context,
@Nullable DraweeConfig draweeConfig) {
sDraweeControllerBuilderSupplier =
new PipelineDraweeControllerBuilderSupplier(context, draweeConfig);
SimpleDraweeView.initialize(sDraweeControllerBuilderSupplier); }
在研究正真的PipelineDraweeController之前,先來看看PipelineDraweeControllerBuilder在Fresco中的構造原理和過程
從上面的函數(shù)我們一個一個往里面點
PipelineDraweeControllerBuilderSupplier是一個提供者模式邮利,主要是為了構造PipelineDraweeControllerBuilder類
圖像管道Drawee contrller builder的具體實現(xiàn)類
這下繼承關系清除了:
SimpleDraweeControllerBuilder
/**
* Interface for simple Drawee controller builders.
*/
simple Drawee controller builders的接口
public interface SimpleDraweeControllerBuilder {
/** Sets the caller context. */
設置調用者上下文
SimpleDraweeControllerBuilder setCallerContext(Object callerContext);
/** Sets the uri. */
設置圖像Uri
SimpleDraweeControllerBuilder setUri(Uri uri);
/** Sets the uri from a string. */
設置圖像Uri
SimpleDraweeControllerBuilder setUri(@Nullable String uriString);
/** Sets the old controller to be reused if possible. */
如果有可能涂佃,設置舊的controller 用以重用
SimpleDraweeControllerBuilder setOldController(@Nullable DraweeController oldController);
/** Builds the specified controller. */
構建具體的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;
圖片請求 ImageRequest
private @Nullable REQUEST mImageRequest;
底分辨率圖片請求
private @Nullable REQUEST mLowResImageRequest;
多圖片請求
private @Nullable REQUEST[] mMultiImageRequests;
private boolean mTryCacheOnlyFirst;
數(shù)據源提供者
private @Nullable Supplier<DataSource<IMAGE>> mDataSourceSupplier;
private @Nullable ControllerListener<? super INFO> mControllerListener;
private @Nullable ControllerViewportVisibilityListener mControllerViewportVisibilityListener;
是否可點擊重試
private boolean mTapToRetryEnabled;
是否需要自動播放動畫
private boolean mAutoPlayAnimations;
private boolean mRetainImageOnFailure;
private String mContentDescription;
// old controller to reuse
這個變量重要 重用的DraweeController 宏娄,其具體的對象田盈,就給子類去構建
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;
默認false
mTapToRetryEnabled = false;
默認不自動播放
mAutoPlayAnimations = false;
mOldController = null;
mContentDescription = null;
}
....其他方法
/** Builds a regular controller. */
構建一個常規(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. */
這個抽象類的唯一抽象方法辟拷,又子類去實現(xiàn)構造具體的類
protected abstract AbstractDraweeController obtainController();
...其他方法
AbstractDraweeControllerBuilder 的作用其實就是提供DraweeControllerBuilder所需要的所有成員變量智政,然后具體的變量值交給子類PipelineDraweeControllerBuilder去獲取實現(xiàn)质涛,并設置這些成員變量
PipelineDraweeControllerBuilder源碼:
/**
* Concrete implementation of ImagePipeline Drawee controller builder.
* <p/> See {@link AbstractDraweeControllerBuilder} for more details.
*/
ImagePipeline Drawee controller builder.的具體實現(xiàn)
public class PipelineDraweeControllerBuilder extends AbstractDraweeControllerBuilder<
PipelineDraweeControllerBuilder,
ImageRequest,
CloseableReference<CloseableImage>,
ImageInfo> {
重要的成員變量圖像管道稠歉,final類型,初始化一遍不在變化汇陆,上篇文章中提到可以從ImagePipelineFactory中獲取
private final ImagePipeline mImagePipeline;
重要的成員變量 PipelineDraweeControllerFactory是PipelineDraweeController工廠
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);
}
設置圖片Uri的的本質是: 用此Uri構建圖像請求ImageRequest怒炸,實際上Fresco加載圖片,都是構造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));
}
...其他方法
父級抽象類的抽象方法毡代,重要方法 obtainController横媚。
@Override
protected PipelineDraweeController obtainController() {
先獲取之前設置的OldController
DraweeController oldController = getOldController();
PipelineDraweeController controller;
if (oldController instanceof PipelineDraweeController) {
如果oldController 是PipelineDraweeController的實例 纠炮,就在從controller的實例上修改一些需要的值,不用再實例化一個controller
controller = (PipelineDraweeController) oldController;
controller.initialize(
obtainDataSourceSupplier(),
generateUniqueControllerId(),
getCacheKey(),
getCallerContext(),
mCustomDrawableFactories);
} else {
如果oldcontroller ==null 使用PipelineDraweeControllerFactory重新生成一個新的controller
controller = mPipelineDraweeControllerFactory.newController(
obtainDataSourceSupplier(),
generateUniqueControllerId(),
getCacheKey(),
getCallerContext(),
mCustomDrawableFactories);
}
return controller;
}
...其他方法
}
這個類主要是為了設置一些builder所需要的值灯蝴,并且構造除樂具體的controller恢口。PipelineDraweeController的實例
PipelineDraweeController這個類是真正的DraweeController,這個下一章在分析穷躁。
PipelineDraweeControllerFactory是PipelineDraweeController的工廠類耕肩。用于常見controller實例。
/**
* 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;
}
內部創(chuàng)建PipelineDraweeController 问潭,創(chuàng)建一個controller需要這么多參數(shù)猿诸,所以需要上面講的重用controller的實例,只改變其中的幾個成員變量值就行了狡忙。
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;
}
}