Android Glide源码解析
1.常用特性:
.load()加载资源:1,drawable资源。2,本地File文件。3,uri。4,网络图片url
.placeholder()图片占位符,
.error()图片加载失败时显示
.crossFade()显示图片时执行淡入淡出的动画默认300ms
.dontAnimate()不执行显示图片时的动画
.override()设置图片的大小
.centerCrop()和fitCenter()图片的显示方式
.animate()view动画2个重构方法
.transform()bitmap转换
.bitmapTransform()bitmap转换。比如:旋转,方法,缩小,高斯模糊等等(转换后你就不能使用.centerCrop() .fitCenter() 了。)
.priority(Priority.HIGH)//当前线程的优先级
.thumbnail(0.1f)缩略图,3个重构方法:优先显示原始图片的百分比(10%)
.listener()异常监听
.into();将图片显示到控件,3个构造方法
2.主要类
RequestManager:请求管理,每一个Activity都会创建一个RequestManager,根据对应Activity的生命周期管理该Activity上所以的图片请求。
Egine:加载图片的引擎,根据Request创建EngineJob和DecodeJob。
EngineJob:图片加载。
DecodeJob:图片处理
3.使用例子,对应源码分析
A.使用列子如下:
Glide.with(context)
.asBitmap().load(url)
.apply(requestOptions)
.into(view)
B.源码分析:
A. 第一步Glide.with(context) ->
- Glide.get(context) 获取 Glide单例对像, RequestManagerRetriever 是Glide的成员变量,构造方法中创建。
-
RequestManagerRetriever 管理 生成 RequestManager
RequestManagerRetriever.get(context) 根据context 的类型生陈
RequestManager 对象。
- 获取 FragmemtManager 之前需要 根据 avtivity/Fraament
的FragmentManager 添加一个看不见的Fragment 绑定生命周期 。(RequestManagerFragment),
RequestManager 是 RequestManagerFactory 根据RequestManagerFragment是否对应有FragmentManager , 没有创建FragmentManager对象,然后设置RequestManagerFragment的成员变量。一一对应关系。
绑定生命周期的流程:
ActivityFragment 提供 成员变量 ,ActivityFragmentLifecycle implements Lifecycle ,相当于被观察者,
保存 观察者LifecycleListener 集合lifecycleListeners,
当生命周期变化的时候,调用LifecycleListener 对应回调方法。
public interface Lifecycle {
void addListener(LifecycleListener listener);
void removeListener(LifecycleListener listener);
}
public interface LifecycleListener {
void onStart();
void onStop();
void onDestroy();
}
- 在构造FragmentManager 时候传递构造方方中。
RequestManager implements LifecycleListener
构造方法中,lifecycle.addListener(this);所以
当ActivityFragment 生命周期变化时候,就会回回调到
FragmentManager onStart(), onStop(),onDestroy()
//第一行代码分析完毕,
B .接下来RequestManager 的方法了。asBitmap()
RequestManager
- 成员变量:
(1)Lifecycle lifecycle,用于监听RequestManagerFragment生命周期。
(2)RequestTracker requestTracker, 用于保存当前RequestManager所有的请求和带处理的请求。 - TargetTracker targetTracker implements LifecycleListener 生命周期 通知 target 生命周期的变化
@Override
public void onStart() {
resumeRequests();
targetTracker.onStart();
}
@Override
public void onStop() {
pauseRequests();
targetTracker.onStop();
}
public void resumeRequests() {
Util.assertMainThread();
requestTracker.resumeRequests();
}
public void pauseRequests() {
Util.assertMainThread();
requestTracker.pauseRequests();
}
- 接下来核心方法创建 RequestBuilder对象
public RequestBuilder asDrawable() {
return as(Drawable.class);
}
public RequestBuilder asGif() {
return as(GifDrawable.class).apply(DECODE_TYPE_GIF);
}
public RequestBuilder as(Class resourceClass) {
return new RequestBuilder<>(glide, this, resourceClass);
}
C. load(url) .apply(requestOptions) ,只是将配置保存在
RequestBuilder成员变量当中。
- RequestBuilder对象的
private RequestBuilder loadGeneric(@Nullable Object model) {
this.model = model;
isModelSet = true;
return this;
}
public RequestBuilder apply(@NonNull RequestOptions requestOptions) {
Preconditions.checkNotNull(requestOptions);
this.requestOptions = getMutableOptions().apply(requestOptions);
return this;
}
D.之后发起请求方法 . into(target)
public > Y into(@NonNull Y target) {
return into(target, getMutableOptions());
}
- 取消target上一次请求,发起新请求。
public > Y into(Y target) {
...
Request request = buildRequest(target, options);
Request previous = target.getRequest();
if (request.isEquivalentTo(previous)) {
request.recycle();
if (!Preconditions.checkNotNull(previous).isRunning()) {
previous.begin();
}
return target;
}
requestManager.clear(target);
target.setRequest(request);
//执行请求
requestManager.track(target, request);
return target;
}
- 最后知道RequestBuilder 生成Request ,传递requestManager.track(target, request) ,接下来看看这个方法
void track(Target> target, Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);
}
- targetTracker 管理所有的target 收到生命周期回调
RequestTracker 管理所有的请求,放入集合当中,
- 回到RequestManager 的
- onStart() -> resumeRequests() -> requestTracker.resumeRequests();
- onStop() -> pauseRequests()->requestTracker.pauseRequests();
所以核心是requestTracker 的
resumeRequests (),pauseRequests()
public void pauseRequests() {
isPaused = true;
for (Request request : Util.getSnapshot(requests)) {
if (request.isRunning()) {
request.pause();
pendingRequests.add(request);
}
}
}
public void resumeRequests() {
isPaused = false;
for (Request request : Util.getSnapshot(requests)) {
if (!request.isComplete() && !request.isCancelled() && !request.isRunning()) {
request.begin();
}
}
pendingRequests.clear();
}
根据当前Request 的状态来最后开启或者暂停请求,把还没请求完成的Request 对像保存在pendingRequests( List
Request 对象生成 SingleRequest是唯一实现。
- SingleRequest 的 begin() , pause() 实现
@Override
public void begin() {
// 如果model空的,那么是不能执行的。 这里的model就是前面提到的RequestBuilder中的model
if (model == null) {
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
width = overrideWidth;
height = overrideHeight;
}
onLoadFailed(new GlideException("Received null model"),logLevel);
return;
}
status = Status.WAITING_FOR_SIZE;
// 如果当前的View尺寸已经加载获取到了,那么就会进入真正的加载流程。
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
onSizeReady(overrideWidth, overrideHeight);
} else {
// 反之,当前View还没有画出来,那么是没有尺寸的。
// 这里会调用到ViewTreeObserver.addOnPreDrawListener。
// 等待View的尺寸都ok,才会继续
target.getSize(this);
}
// 如果等待和正在执行状态,那么当前会加载占位符Drawable
if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
&& canNotifyStatusChanged()) {
target.onLoadStarted(getPlaceholderDrawable());
}
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logV("finished run method in " + LogTime.getElapsedMillis(startTime));
}
}
- 总结,target 获取宽高完成之后,直接调用 onSizeReady(overrideWidth, overrideHeight); 加载图片,
没有获取到 target.getSize(this); 获取宽高之后,会回调SizeReadyCallback,也就是SingleRequest 对象,调用SizeReadyCallback.onSizeReady(),流程一样。
public void onSizeReady(int width, int height) {
...
if (status != Status.WAITING_FOR_SIZE) {
return;
}
status = Status.RUNNING;
....
//网络请求真正的去加载图片数据
loadStatus = engine.load(
glideContext,
model,ResourceCallback this )...
}
- engine 加载资源 传递ResourceCallback 回调 ,加载数据结果,
在内部回调 RequestListener 对应方法,通知
RequestBuilder .lister(RequestListener) 给外界
SingleRequest
implements Request,SizeReadyCallback,ResourceCallback FactoryPools.Poolable
public interface ResourceCallback {
void onResourceReady(Resource> resource, DataSource dataSource);
void onLoadFailed(GlideException e);
}
- SingleRequest onResourceReady(),onLoadFailed()就是通知加载完成后target 处理工作。
接下来就是Engine.load()方法流程来: