我以为使用第三方的库时,要作到 知其然 知其因此然 欲然革之 弃之天然 好吧不装x了说人话就是,对一个库的了解程度能够化为为这样几个等级:缓存
总体Glide是怎样架构的,大轮子如何转动起来,经过这篇文章对Glide的总体有个认识而后逐一突破。 (这图画我了俩小时....,手动比心,求赞) bash
Glide的简单使用是下面这样的:网络
Glide.with(context).load("http:xxxx").into(target)
复制代码
先看看Glide.with()方法作了什么。Glide的with(x)方法的参数能够是:Context、Activity、Fragment、View。 不管是哪一种参数都会直接或者间接的调用下面这个方法:架构
private static RequestManagerRetriever getRetriever(@Nullable Context context){
Preconditions.checkNotNull(context,"..");
return Glide.get(context).getRequestManagerRetriever();
}
复制代码
这个方法最终会返回一个RequestManagerRetriever对象。Glide.get(ctx)返回的是一个Glide对象,内部使用的单例模式,进程内Glide是单例,以下。敲黑板,这不就是传说中的双重效验锁。app
@NonNull
public static Glide get(@NonNull Context context) {
if (glide == null) {
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context);
}
}
}
return glide;
}
复制代码
找到了Glide建立的地方,Glide.get(ctx)->checkAndInitializeGlide(ctx)->initializeGlide(ctx,glideBuilder),最终建立glide单例对象的重担落在了initializeGlide(..)方法上ide
private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
Context applicationContext = context.getApplicationContext();
GeneratedAppGlideModule annotationGeneratedModulegetAnnotationGeneratedGlideModules();
....
Glide glide = builder.build(applicationContext);
...
applicationContext.registerComponentCallbacks(glide);
Glide.glide = glide;
}
复制代码
咱们源码中关于使用APT技术动态加载GeneratedAppGlideModule对象而后配置Glide相关代码隐去了,篇幅有限这一部分单独成篇详细探究。ui
先看这个方法主要完成了三件事:this
# GlideBuild
Glide build(@NonNull Context context) {
if (sourceExecutor == null) {...}
if (diskCacheExecutor == null) {...}
if (animationExecutor == null) {...}
...
if (memoryCache == null) {...}
if (diskCacheFactory == null) {...}
if (engine == null) {...}
return new Glide(context, engine,memoryCache,bitmapPool,arrayPool...)
}
复制代码
如上图通过层层最终调用initializeGlide(),这个方法中使用GlideBuilder对象够建出Glide对象,值得关注的是他是一个单例。并且当在GlideBuider没有设置响应参数的时候会生成默认的参数供GlideBuilder建立出Glide对象。spa
书接上回,咱们已经对Glide这个类的建立有了一个大致的认知。操作系统
仍是那行代码,
RequestManager requestManager = Glide.with(this);
复制代码
这行代码顺序的作了三件事
RequestManagerReriever类的注释
A collection of static methods for creating new RequestManagers or retrieving existing ones from activities and fragment.
这个类的职责就是建立新的RequestManager或者在activity和fragment中检索出已经存在的。
建立一个RequestManager的资料中很重要的一个就是LifeCycle
摘了比较核心的一段代码标记,加了注释。
private RequestManager fragmentGet(@NonNull Context context,FragmentManager fm,Fragment parentHint,boolean isParentVisible) {
//获取一个RequestManagerFragment
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
//试图在RequestManagerFragment中获取requestManager
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
//若是为空就建立一个而且存到RequestManagerFragment中
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
复制代码
注意的点
总结下RequestManagerReriever对象建立RequestManager流程。
RequestManager见名知意,管理图片请求,启动、暂停、从新启动请求,依据所在组件的生命周期周期和网络作出恰当的动做
使用RequestManager对象一系列的load()方法最终可以获得一个RequestBuilder的对象, RequestBuilder是一个泛型类,加载什么样的类型图片资源决定了他是什么类型,图片资源的来源多是Recource、File、或者网络。
RequestBuilder<T> requestBuidlder = requestManager.load(xxxx);
复制代码
获得RequestBuilder以后,就能够对请求的图片资源作一些指望设置
RequestBuildler,均可以经过RequestOptions进行配置。ReuqestBuilder继承了BaseRequestOptions类,BaseRequestOption这个类是链接RequestOption和RequestBuilder的桥梁,经过这个类的对象对RequestOption进行一系列的设置。
Request有三个实现类,RequestCoordinator,SingleRequest和ErrorRequestCoordinator,RequestCoodinator。
#RequestBuilder 构建ErrorRequestCoordinator对象的方法为例。
private Request buildRequestRecursive(..) {
//构建请求控制
ErrorRequestCoordinator errorRequestCoordinator = null;
if (errorBuilder != null) {
errorRequestCoordinator = new ErrorRequestCoordinator(parentCoordinator);
parentCoordinator = errorRequestCoordinator;
}
//构建的主请求
Request mainRequest =(...);
if (errorRequestCoordinator == null) {
return mainRequest;
}
int errorOverrideWidth = errorBuilder.getOverrideWidth();
int errorOverrideHeight = errorBuilder.getOverrideHeight();
if (Util.isValidDimensions(overrideWidth, overrideHeight)
&& !errorBuilder.isValidOverride()) {
errorOverrideWidth = requestOptions.getOverrideWidth();
errorOverrideHeight = requestOptions.getOverrideHeight();
}
//构建错误请求
Request errorRequest =
errorBuilder.buildRequestRecursive(..);
errorRequestCoordinator.setRequests(mainRequest, errorRequest);
return errorRequestCoordinator;
}
复制代码
整个Request构建管理的构成以下
Request对象的begin()方法根据图片不一样的来源去加载,获取到指望尺寸以后就会调用onSizeReady(),传入一系列参数信息。
onSizeReady(){
...
loadStatus =
engine.load(
glideContext,
model,
requestOptions.getSignature(),
this.width,
this.height,
requestOptions.getResourceClass(),
transcodeClass,
priority,
requestOptions.getDiskCacheStrategy(),
requestOptions.getTransformations(),
requestOptions.isTransformationRequired(),
requestOptions.isScaleOnlyOrNoTransform(),
requestOptions.getOptions(),
requestOptions.isMemoryCacheable(),
requestOptions.getUseUnlimitedSourceGeneratorsPool(),
requestOptions.getUseAnimationPool(),
requestOptions.getOnlyRetrieveFromCache(),
this,
callbackExecutor);
...
}
复制代码
engin.load()
public synchronized <R> LoadStatus load(...) {
...
EngineJob<R> engineJob =engineJobFactory.build(...);
DecodeJob<R> decodeJob =decodeJobFactory.build(...);
...
engineJob.addCallback(cb, callbackExecutor);//加载
engineJob.start(decodeJob);//解码,对二进制数据转换成图片根据配置进行编辑
...
return new LoadStatus(cb, engineJob);
}
复制代码
EngineJob.load实际加载图片数据的执行者,加载完以后交给decodeJob处理。内部具体如何实现的单独成篇分析,如这部分中线程池如何使用,Bitmap的使用技巧等。
以上对Glide这个优秀的开源库有了一个总体的认识,大致分为三个部分