一、Glide中几个典型的类
1、RequestManagerRetriever 用于生成RequestManager的类
public class RequestManagerRetriever implements Handler.Callback {
/** The top application level RequestManager. */
private volatile RequestManager applicationManager;
private final Handler handler;
private final RequestManagerFactory factory;
@NonNull
public RequestManager get(@NonNull Context context) {
if (context == null) {
throw new IllegalArgumentException("You cannot start a load on a null Context");
} else if (Util.isOnMainThread() && !(context instanceof Application)) {
//step 0
if (context instanceof FragmentActivity) {
return get((FragmentActivity) context);
//step 1
} else if (context instanceof Activity) {
return get((Activity) context);
//step 2
} else if (context instanceof ContextWrapper
// Only unwrap a ContextWrapper if the baseContext has a non-null application context.
// Context#createPackageContext may return a Context without an Application instance,
// in which case a ContextWrapper may be used to attach one.
&& ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
return get(((ContextWrapper) context).getBaseContext());
}
}
//step 3
return getApplicationManager(context);
}
@NonNull
private RequestManager getApplicationManager(@NonNull Context context) {
// Either an application context or we're on a background thread.
if (applicationManager == null) {
synchronized (this) {
if (applicationManager == null) {
// Normally pause/resume is taken care of by the fragment we add to the fragment or
// activity. However, in this case since the manager attached to the application will not
// receive lifecycle events, we must force the manager to start resumed using
// ApplicationLifecycle.
Glide glide = Glide.get(context.getApplicationContext());
applicationManager =
factory.build(
glide,
new ApplicationLifecycle(),
new EmptyRequestManagerTreeNode(),
context.getApplicationContext());
}
}
}
return applicationManager;
}
public interface RequestManagerFactory {
@NonNull
RequestManager build(
@NonNull Glide glide,
@NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode requestManagerTreeNode,
@NonNull Context context);
}
private static final RequestManagerFactory DEFAULT_FACTORY =
new RequestManagerFactory() {
@NonNull
@Override
public RequestManager build(
@NonNull Glide glide,
@NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode requestManagerTreeNode,
@NonNull Context context) {
return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
}
};
}
}
RequestManagerRetriever 生成了RequestManager 有两类:
- (1) applicationManager ,该类型的RequestManager 的声明周期和Application相同
- (2)可以感知Activity声明周期的RequestManager,当Activity onPause之后 会停止图片的加载
RequestManagerRetriever.get()方法有很多重载,
- 当传入的参数 Application 或者app在后台时,会创建ApplicationRequestManager,声明周期与Application同步
- 当传入的参数是Activty、Fragment或view时,创建的RequestManager 会与Activity的生命周期同步。
生命周期的长短,区别就在于RequestManager构造时传入lifecycle对象
RequestManager是如何监听Activity的声明周期的?
@NonNull
public RequestManager get(@NonNull Fragment fragment) {
if (Util.isOnBackgroundThread()) {
return get(fragment.getContext().getApplicationContext());
} else {
FragmentManager fm = fragment.getChildFragmentManager();
//step 1
return supportFragmentGet(fragment.getContext(), fm, fragment, fragment.isVisible());
}
}
@NonNull
private RequestManager supportFragmentGet(
@NonNull Context context,
@NonNull FragmentManager fm,
@Nullable Fragment parentHint,
boolean isParentVisible) {
//step 2 创建SupportRequestManagerFragment 获取Activity生命周期
SupportRequestManagerFragment current =
getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
//step 4 将创建的requestManager保存到SupportRequestManagerFragment中
current.setRequestManager(requestManager);
}
return requestManager;
}
@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
@NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
SupportRequestManagerFragment current =
(SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
//step 3 创建一个SupportRequestManagerFragment 对象,加入到fragmentManager当中,SupportRequestManagerFragment中持有一个ActivityFragmentLifecycle 和RequestManager
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
if (isParentVisible) {
current.getGlideLifecycle().onStart();
}
pendingSupportRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
- supportFragmentGet() 生成一个SupportRequestManagerFragment 的Fragment对象,加入到FragmentManager中,这样生成一个SupportRequestManagerFragment就有了生命周期
- SupportRequestManagerFragment 持有一个ActivityFragmentLifecycle对象,其生命周期与SupportRequestManagerFragment同步,是对外传递lifecycle的桥梁
- 创建一个RequestManager对象,并将它保存在SupportRequestManagerFragment中
- 将ActivityFragmentLifecycle生命周期对象传递到RequestManager中,使其可以感知Activity生命周期。
2、RequestManager
RequestManager 负责管理Request,它持有requestTracker和TargetTracker。
同一个Activity(针对非Application类型的Context) 对应一个RequestManager,管理该Activity内所有glide请求。
public class RequestManager
implements ComponentCallbacks2, LifecycleListener, ModelTypes> {
protected final Glide glide;//全局glide实例
protected final Context context;
final Lifecycle lifecycle; //感知声明周期
//step 0 持有requestTracker和TargetTracker实例
private final RequestTracker requestTracker;//追踪request
private final TargetTracker targetTracker = new TargetTracker();//追踪target
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
this.glide = glide;
this.lifecycle = lifecycle;
this.treeNode = treeNode;
this.requestTracker = requestTracker;
this.context = context;
//step 1 感知网络连接变化
connectivityMonitor =
factory.build(
context.getApplicationContext(),
new RequestManagerConnectivityListener(requestTracker));
if (Util.isOnBackgroundThread()) {
mainHandler.post(addSelfToLifecycle);
} else {
//step 2 感知生命周期
lifecycle.addListener(this);
}
lifecycle.addListener(connectivityMonitor);
defaultRequestListeners =
new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
glide.registerRequestManager(this);
}
//step 3 声明周期变化
@Override
public synchronized void onStart() {
resumeRequests();
targetTracker.onStart();
}
@Override
public synchronized void onStop() {
pauseRequests();
targetTracker.onStop();
}
@Override
public synchronized void onDestroy() {
targetTracker.onDestroy();
for (Target> target : targetTracker.getAll()) {
clear(target);
}
targetTracker.clear();
requestTracker.clearRequests();
lifecycle.removeListener(this);
lifecycle.removeListener(connectivityMonitor);
mainHandler.removeCallbacks(addSelfToLifecycle);
glide.unregisterRequestManager(this);
}
//step 4 构建RequestBuilder
public RequestBuilder asBitmap() {
return as(Bitmap.class).apply(DECODE_TYPE_BITMAP);
}
public RequestBuilder asGif() {
return as(GifDrawable.class).apply(DECODE_TYPE_GIF);
}
public RequestBuilder asDrawable() {
return as(Drawable.class);
}
public RequestBuilder as(
@NonNull Class resourceClass) {
return new RequestBuilder<>(glide, this, resourceClass, context);
}
public RequestBuilder load(@Nullable Bitmap bitmap) {
return asDrawable().load(bitmap);
}
}
- RequestManager 可以感知网络连接变化,当网络连接恢复时,可以重新开启图片请求,如step 1
- RequestManager 可以感知声明周期,当生命周期变化时暂停、恢复Request,如step2 和step3
- RequestManager另一个作用是 构造RequestBuilder对象,如step 4
3、RequestBuilder
RequestBuilder 是用于构造Request的。
RequestBuilder 继承与BaseRequestOptions
我们先来看一下BaseRequestOptions,它用来记录request请求的配置信息,如展位图、优先级、图形变换等
public abstract class BaseRequestOptions> implements Cloneable {
private static final int UNSET = -1;
private static final int SIZE_MULTIPLIER = 1 << 1;
private static final int DISK_CACHE_STRATEGY = 1 << 2;
private static final int PRIORITY = 1 << 3;
private static final int ERROR_PLACEHOLDER = 1 << 4;
private static final int ERROR_ID = 1 << 5;
private static final int PLACEHOLDER = 1 << 6;
private static final int PLACEHOLDER_ID = 1 << 7;
private static final int IS_CACHEABLE = 1 << 8;
private static final int OVERRIDE = 1 << 9;
private static final int SIGNATURE = 1 << 10;
private static final int TRANSFORMATION = 1 << 11;
private static final int RESOURCE_CLASS = 1 << 12;
private static final int FALLBACK = 1 << 13;
private static final int FALLBACK_ID = 1 << 14;
private static final int THEME = 1 << 15;
private static final int TRANSFORMATION_ALLOWED = 1 << 16;
private static final int TRANSFORMATION_REQUIRED = 1 << 17;
private static final int USE_UNLIMITED_SOURCE_GENERATORS_POOL = 1 << 18;
private static final int ONLY_RETRIEVE_FROM_CACHE = 1 << 19;
private static final int USE_ANIMATION_POOL = 1 << 20;
//BaseRequestOptions request请求的参数配置信息
//step 0 fields 32bit整型,用特定的bit位 表示是否设置了某项配置.
private int fields;
//step 1 用下面的属性 来记录具体的配置信息
private float sizeMultiplier = 1f; //放缩系数
//缓存策略
@NonNull private DiskCacheStrategy diskCacheStrategy = DiskCacheStrategy.AUTOMATIC;
//优先级
@NonNull private Priority priority = Priority.NORMAL;
//加载失败的占位图Drawable
@Nullable private Drawable errorPlaceholder;
//加载失败的占位图资源ID
private int errorId;
@Nullable private Drawable placeholderDrawable;
private int placeholderId;
private boolean isCacheable = true;
//指定宽高
private int overrideHeight = UNSET;
private int overrideWidth = UNSET;
//请求对应的唯一的key
@NonNull private Key signature = EmptySignature.obtain();
private boolean isTransformationRequired;
private boolean isTransformationAllowed = true;
@Nullable private Drawable fallbackDrawable;
private int fallbackId;
@NonNull private Options options = new Options();
//图形变换数组
@NonNull
private Map, Transformation>> transformations = new CachedHashCodeArrayMap<>();
//最终请求的资源类型,如Drawable、bitmap、gifDrawable等
@NonNull private Class> resourceClass = Object.class;
private boolean isLocked;
@Nullable private Resources.Theme theme;
private boolean isAutoCloneEnabled;
private boolean useUnlimitedSourceGeneratorsPool;
private boolean onlyRetrieveFromCache;
private boolean isScaleOnlyOrNoTransform = true;
private boolean useAnimationPool;
}
BaseRequestOptions 设置配置项时需要同时设置配置项和fileds字段(表示设置了某项配置)
public T diskCacheStrategy(@NonNull DiskCacheStrategy strategy) {
if (isAutoCloneEnabled) {
return clone().diskCacheStrategy(strategy);
}
this.diskCacheStrategy = Preconditions.checkNotNull(strategy);
fields |= DISK_CACHE_STRATEGY;
return selfOrThrowIfLocked();
}
RequestBuilder 继承自BaseRequestOptions
使用来构造Request的。
public class RequestBuilder extends BaseRequestOptions>
implements Cloneable, ModelTypes> {
protected static final RequestOptions DOWNLOAD_ONLY_OPTIONS =
new RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.DATA)
.priority(Priority.LOW)
.skipMemoryCache(true);
//step 0 首先 RequestBuilder 是用来构建请求的, 它继承自BaseRequestOptions,承载了众多的加载配置项
private final Context context;
//step 1 持有RequestManager、全局的Glide和GlideContext
private final RequestManager requestManager;
private final Glide glide;
private final GlideContext glideContext;
//step 2 补充了额外的配置选项
//指定待加载的资源(数据源),可以是string,URL、URI、ReqsourceID、File等
@Nullable private Object model;
//是否设置过model
private boolean isModelSet;
//指最终输出的资源类型,如Drawable、bitmap等
private final Class transcodeClass;
//指定动画过渡效果
private TransitionOptions, ? super TranscodeType> transitionOptions;
//制定了Requestlistner
@Nullable private List> requestListeners;
@Nullable private RequestBuilder thumbnailBuilder;
@Nullable private RequestBuilder errorBuilder;
@Nullable private Float thumbSizeMultiplier;
private boolean isDefaultTransitionOptionsSet = true;
private boolean isThumbnailBuilt;
//step 3 load方法,设置数据源
public RequestBuilder load(@Nullable String string) {
return loadGeneric(string);
}
private RequestBuilder loadGeneric(@Nullable Object model) {
this.model = model;
isModelSet = true;
return this;
}
//step 4 into()方法传入Target
public > Y into(@NonNull Y target) {
return into(target, /*targetListener=*/ null, Executors.mainThreadExecutor());
}
@Synthetic
> Y into(
@NonNull Y target,
@Nullable RequestListener targetListener,
Executor callbackExecutor) {
return into(target, targetListener, /*options=*/ this, callbackExecutor);
}
private > Y into(
@NonNull Y target,
@Nullable RequestListener targetListener,
BaseRequestOptions> options,
Executor callbackExecutor) {
Preconditions.checkNotNull(target);
if (!isModelSet) {
throw new IllegalArgumentException("You must call #load() before calling #into()");
}
Request request = buildRequest(target, targetListener, options, callbackExecutor);
Request previous = target.getRequest();
if (request.isEquivalentTo(previous)
&& !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
if (!Preconditions.checkNotNull(previous).isRunning()) {
previous.begin();
}
return target;
}
requestManager.clear(target);
target.setRequest(request);
requestManager.track(target, request);
return target;
}
public ViewTarget into(@NonNull ImageView view) {
Util.assertMainThread();
Preconditions.checkNotNull(view);
BaseRequestOptions> requestOptions = this;
if (!requestOptions.isTransformationSet()
&& requestOptions.isTransformationAllowed()
&& view.getScaleType() != null) {
switch (view.getScaleType()) {
case CENTER_CROP:
requestOptions = requestOptions.clone().optionalCenterCrop();
break;
case CENTER_INSIDE:
requestOptions = requestOptions.clone().optionalCenterInside();
break;
case FIT_CENTER:
case FIT_START:
case FIT_END:
requestOptions = requestOptions.clone().optionalFitCenter();
break;
case FIT_XY:
requestOptions = requestOptions.clone().optionalCenterInside();
break;
case CENTER:
case MATRIX:
default:
// Do nothing.
}
}
return into(
glideContext.buildImageViewTarget(view, transcodeClass),
/*targetListener=*/ null,
requestOptions,
Executors.mainThreadExecutor());
}
}
a、它持有RequestManager、全局的Glide和GlideContext
b、除了基本的配置项之外,补充了额外的配置选项,如
- model数据源、
- transcodeClass 最终的要获取的资源类型,如Drawable、bitmap等
- transitionOptions 动画过渡效果
- requestListeners 请求监听器
c、RequestBuilder的一个重要方法load 用于指定数据源
4、into(target) 方法,用于生成Request,并将结果传递给Target
4、Target
a、Target是一个interface接口,继承自LifecycleListener
public interface Target extends LifecycleListener {
//开始加载图片,显示placheholder
void onLoadStarted(@Nullable Drawable placeholder);
//加载失败,显示errorDrawable
void onLoadFailed(@Nullable Drawable errorDrawable);
//request取消,加载fallback Drawable
void onLoadCleared(@Nullable Drawable placeholder);
//下载成功,回调onResourceReady
void onResourceReady(@NonNull R resource, @Nullable Transition super R> transition);
//请求图片的尺寸
void getSize(@NonNull SizeReadyCallback cb);
void removeCallback(@NonNull SizeReadyCallback cb);
//保存request对象
void setRequest(@Nullable Request request);
Request getRequest();
}
public interface LifecycleListener {
void onStart();
void onStop();
void onDestroy();
}
Target 具有LifecycleListener的能力,可以感知生命周期(onStrat、onStop、onDestroy)
同时具有以下能力
- onLoadStarted,开始加载图片,显示placheholder
- onLoadFailed,加载失败,显示errorDrawable
- request取消,加载fallback Drawable
- onResourceRead,下载成功,将resource资源回调给Target
- getSize,请求图片尺寸
- setRequest(),getRequest() 持有Request对象
b、BaseTarget
BaseTarget 持有request属性,实现了setRequest、getRequest方法
public abstract class BaseTarget implements Target {
private Request request;
@Override
public void setRequest(@Nullable Request request) {
this.request = request;
}
@Override
@Nullable
public Request getRequest() {
return request;
}
//其他父类方法
...
}
c、ViewTarget
ViewTarget 集成自BaseTarget,持有一个View对象。
- Request 保存在了view对象的tag中
- 实现了getSize() ,通过SizeDeterminer 计算Bitmap 最终的尺寸,再通过SizeReadyCallback进行回调.
- 注册了View的OnAttachStateChangeListener,onViewAttachedToWindow时resumeRequest,onViewDetachedFromWindow时 pauseRequest
public abstract class ViewTarget extends BaseTarget {
//step 0 ViewTarget 持有一个View
protected final T view;
private final SizeDeterminer sizeDeterminer;
@Nullable private OnAttachStateChangeListener attachStateListener;
public ViewTarget(@NonNull T view) {
this.view = Preconditions.checkNotNull(view);
sizeDeterminer = new SizeDeterminer(view);
}
//step 2 实现了计算ImageView尺寸的方式,通过sizeDeterminer计算,计算完成通过SizeReadyCallback 回传
public void getSize(@NonNull SizeReadyCallback cb) {
sizeDeterminer.getSize(cb);
}
@Override
public void setRequest(@Nullable Request request) {
setTag(request);
}
//step 1 request 保存在了View的Tag上
private void setTag(@Nullable Object tag) {
isTagUsedAtLeastOnce = true;
view.setTag(tagId, tag);
}
//step 2 监测View的attach, attach时 resumeRequest,dettach时pauseRequest
public final ViewTarget clearOnDetach() {
if (attachStateListener != null) {
return this;
}
attachStateListener =
new OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
resumeMyRequest();
}
@Override
public void onViewDetachedFromWindow(View v) {
pauseMyRequest();
}
};
maybeAddAttachStateListener();
return this;
}
}
d、 ImageViewTarget
ImageViewTarget 继承自ViewTarget,重点实现的是Animatable动画相关的操作
public abstract class ImageViewTarget extends ViewTarget
implements Transition.ViewAdapter {
@Nullable private Animatable animatable;
//step 0 实现了Transition.ViewAdapter
public Drawable getCurrentDrawable() {
return view.getDrawable();
}
public void setDrawable(Drawable drawable) {
view.setImageDrawable(drawable);
}
//step 1 实现了onLoadFailed()、onLoadFailed()、onLoadCleared(), 显示placheHolder、errorDrawable、fallbackDrawable
public void onLoadStarted(@Nullable Drawable placeholder) {
super.onLoadStarted(placeholder);
setDrawable(placeholder);
}
public void onLoadFailed(@Nullable Drawable errorDrawable) {
super.onLoadFailed(errorDrawable);
setDrawable(errorDrawable);
}
public void onLoadCleared(@Nullable Drawable placeholder) {
super.onLoadCleared(placeholder);
if (animatable != null) {
animatable.stop();
}
setDrawable(placeholder);
}
//实现了onResourceReady 资源备妥后 显示动画
@Override
public void onResourceReady(@NonNull Z resource, @Nullable Transition super Z> transition) {
if (transition == null || !transition.transition(resource, this)) {
setResourceInternal(resource);
} else {
maybeUpdateAnimatable(resource);
}
}
//step 2 onStart()启动动画,onStop() 通知动画
@Override
public void onStart() {
if (animatable != null) {
animatable.start();
}
}
@Override
public void onStop() {
if (animatable != null) {
animatable.stop();
}
}
protected abstract void setResource(@Nullable Z resource);
}
- 实现了Transition.ViewAdapter 接口
Transition.ViewAdapter
public interface Transition {
interface ViewAdapter {
View getView();
Drawable getCurrentDrawable();
void setDrawable(Drawable drawable);
}
}
实现了onLoadFailed()、onLoadFailed()、onLoadCleared() 方法,分别显示placheHolder,errorDrawable、fallbackDrawable
实现onResourceReady 动画显示Drawable
生命周期onStart()、onStop() 启动或停止动画
setResource() 是个虚方法,留给子类实现
e、BitmapImageViewTarget
BitmapImageViewTarget 继承自ImageViewTarget,指定了Resource的类型为Bitmap,实现了setResource方法
public class BitmapImageViewTarget extends ImageViewTarget {
// Public API.
@SuppressWarnings("WeakerAccess")
public BitmapImageViewTarget(ImageView view) {
super(view);
}
/**
*
* @param resource The bitmap to display.
*/
@Override
protected void setResource(Bitmap resource) {
view.setImageBitmap(resource);
}
}
f、DrawableImageViewTarget
DrawableImageViewTarget 继承自ImageViewTarget,指定了Resource类型为Drawable,并实现了setResource方法
public class DrawableImageViewTarget extends ImageViewTarget {
public DrawableImageViewTarget(ImageView view) {
super(view);
}
@Override
protected void setResource(@Nullable Drawable resource) {
view.setImageDrawable(resource);
}
}
7、Request
Request 实现将resource加载到Target中,是一个接口,具体实现由子类实现。
//一个Request 实现如何加载resource到Target中
public interface Request {
//开始异步加载
void begin();
//停止加载,释放资环
void clear();
void pause();
boolean isRunning();
boolean isComplete();
boolean isCleared();
boolean isAnyResourceSet();
boolean isEquivalentTo(Request other);
}
SingleRequest 是Request的实现类,SingleRequest内部定义了一个Status枚举,标记Request请求所处的阶段
public final class SingleRequest implements Request, SizeReadyCallback, ResourceCallback {
private enum Status {
/** Created but not yet running. */
PENDING,
/** In the process of fetching media. */
RUNNING,
/** Waiting for a callback given to the Target to be called to determine target dimensions. */
WAITING_FOR_SIZE,
/** Finished loading media successfully. */
COMPLETE,
/** Failed to load media, may be restarted. */
FAILED,
/** Cleared by the user with a placeholder set, may be restarted. */
CLEARED,
}
}
- PENDING :Request刚创建,尚未执行
- WAITING_FOR_SIZE:等待获取Target的尺寸,获取成功后,会通过callback 传递到Request的onSizeReady()
- RUNNING:Target尺寸确定了之后,进入Running状态,开始加载Resource
- COMPLETE:加载成功,status切换为成功状态
- FAILED:加载失败状态
- CLEARED:资源被清除
所以常规的状态流应该是:
PENDING->WAITING_FOR_SIZE->RUNNING->COMPLETE
二、glide使用三板斧
Glide.with(iv_glide).load(url).into(iv_glide)
1、with 操作符返回一个RequestManager
Glide.with(context) 返回一个RequestManager
public static RequestManager with(@NonNull View view) {
return getRetriever(view.getContext()).get(view);
}
- step == 0 Glide.get()会进行Glide的全局初始化
- step == 1 getRetriever() 获取以一个RequestManagerRetriever对象
- step == 2 RequestManagerRetriever.get() 返回一个RequestManger对象
glide.with()可以传入不同的context,返回不同的RequestManager
public RequestManager get(@NonNull Context context) {
if (context == null) {
throw new IllegalArgumentException("You cannot start a load on a null Context");
} else if (Util.isOnMainThread() && !(context instanceof Application)) {
if (context instanceof FragmentActivity) {
return get((FragmentActivity) context);
} else if (context instanceof Activity) {
return get((Activity) context);
} else if (context instanceof ContextWrapper
// Only unwrap a ContextWrapper if the baseContext has a non-null application context.
// Context#createPackageContext may return a Context without an Application instance,
// in which case a ContextWrapper may be used to attach one.
&& ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
return get(((ContextWrapper) context).getBaseContext());
}
}
return getApplicationManager(context);
}
以传入FragmentActivity为例子,
- 当前处于后台时,会创建给ApplciationRequestManager
- 当处于前台时,会创建一个无界面的SupportRequestManagerFragment 加入到FragmentManager中,SupportRequestManagerFragment中维护一个ActivityFragmentLifecycle,与Activity生命周期同步,此lifeCycle会传递到Request中,感知Activity声明周期。
@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
@NonNull
private RequestManager supportFragmentGet(
@NonNull Context context,
@NonNull FragmentManager fm,
@Nullable Fragment parentHint,
boolean isParentVisible) {
SupportRequestManagerFragment current =
getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
// TODO(b/27524013): Factor out this Glide.get() call.
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
2、load 操作符返回RequestBuilder
RequestManager.load方法返回RequestBuilder对象,并指定了数据源(如图片加载链接)
RequestManager.hava
public RequestBuilder load(@Nullable String string) {
return asDrawable().load(string);
}
public RequestBuilder asDrawable() {
return as(Drawable.class);
}
public RequestBuilder as(
@NonNull Class resourceClass) {
return new RequestBuilder<>(glide, this, resourceClass, context);
}
- load默认是产生RequestBuilder
,指定输出的resource类型是Drawable - asBitmap、asGif 方法可以指定资源类型为Bitmap或者GifDrawable
public RequestBuilder asBitmap() {
return as(Bitmap.class).apply(DECODE_TYPE_BITMAP);
}
public RequestBuilder asGif() {
return as(GifDrawable.class).apply(DECODE_TYPE_GIF);
}
- RequestBuilder 链式调用可以指定Request的各种配置和属性
Glide.with(iv_glide)
.load(url)
.placeholder(R.drawable.ic_launcher_background)
.error(R.drawable.ic_launcher_foreground)
.fallback(R.drawable.ic_launcher_foreground)
.transform(RoundTransformation(50), RotateTransformation(90F))
.transition(DrawableTransitionOptions.withCrossFade(1000 * 10))
.into(iv_glide)
3、into操作符
into操作符传入一个ImageView,触发图片获取和加载
public ViewTarget into(@NonNull ImageView view) {
//step 0 生成一个BitMapImageViewTarget 或者DrawableImageViewTarget
return into(
glideContext.buildImageViewTarget(view, transcodeClass),
/*targetListener=*/ null,
requestOptions,
Executors.mainThreadExecutor());
}
private > Y into(
@NonNull Y target,
@Nullable RequestListener targetListener,
BaseRequestOptions> options,
Executor callbackExecutor) {
Preconditions.checkNotNull(target);
//step 1 构造一个SingleRequest
Request request = buildRequest(target, targetListener, options, callbackExecutor);
requestManager.clear(target);
target.setRequest(request);
//step 2 通过requestManager 追踪,启动 SingleRequest的执行
requestManager.track(target, request);
return target;
}
- 首先通过传入的ImageView 构造了,根据TranscodeType 生成了一个ImageViewTarget
public class ImageViewTargetFactory {
@NonNull
@SuppressWarnings("unchecked")
public ViewTarget buildTarget(
@NonNull ImageView view, @NonNull Class clazz) {
if (Bitmap.class.equals(clazz)) {
return (ViewTarget) new BitmapImageViewTarget(view);
} else if (Drawable.class.isAssignableFrom(clazz)) {
return (ViewTarget) new DrawableImageViewTarget(view);
} else {
throw new IllegalArgumentException(
"Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
}
}
}
- 通过上一步生成的ImageViewTarget,构造SingleRequest
- 将SingleRequest 传入requestManager,触发图片的加载过程。
requestManager.track(target, request);
##RequestManager.java
synchronized void track(@NonNull Target> target, @NonNull Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);
}
RequestTracker.java
public void runRequest(@NonNull Request request) {
requests.add(request);
if (!isPaused) {
request.begin();
} else {
request.clear();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Paused, delaying request");
}
pendingRequests.add(request);
}
}
至此Glide操作的三板斧执行完毕
三、Reqeust 请求是如何执行的
3.1、RequestBuilder.into()方式是真正图片加载的入口
RequestBuilder.java
public ViewTarget into(@NonNull ImageView view){
//step 0 产生ImageViewTarget
target = glideContext.buildImageViewTarget(view, transcodeClass)
//step 1 生成一个SingleRequest对象
Request request = buildRequest(target, targetListener, options, callbackExecutor);
//先取消target上的图片加载(如果有的话)
requestManager.clear(target);
target.setRequest(request);
//step 2 将target、request加入到requestManager
requestManager.track(target, request);
}
#RequestManager.java
synchronized void track(@NonNull Target> target, @NonNull Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);
}
#RequestTracker.java
public void runRequest(@NonNull Request request) {
//step 3 将request加入到requests队列
requests.add(request);
if (!isPaused) { //RequestTracker不是pause状态,则直接启动request
request.begin();
} else { //RequestTracker处于pause状态,则将request加入到pendingRequest待执行Request队列
request.clear();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Paused, delaying request");
}
pendingRequests.add(request);
}
}
代码的调用流程为
RequestBuilder.into()->
RequestMananger.track()->
requestTracker.runRequest()->
request.begin()
3.2、request.begin()
request 实际SingleRequest实例
#SingleRequest.java
public void begin() {
//step 0 model 为空 -> onLoadFailed
if (model == null) {
onLoadFailed(new GlideException("Received null model"), logLevel);
return;
}
// 正在执行的Request不允许再次执行
if (status == Status.RUNNING) {
throw new IllegalArgumentException("Cannot restart a running request");
}
//执行完成,回调onResourceReady 回传图片文件
if (status == Status.COMPLETE) {
onResourceReady(resource, DataSource.MEMORY_CACHE);
return;
}
// step 1 最初status状态 是WAITING_FOR_SIZE,等待获取目标图片大小
status = Status.WAITING_FOR_SIZE;
//如果指定了overrideWidth和overrideHeight 则直接使用回调onSizeReady()
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
onSizeReady(overrideWidth, overrideHeight);
} else {
//用于未指定图片大小,则交由target取获取目标图片的大小(对于ImageViewTarget size一般是ImageViewK控件的尺寸)
target.getSize(this);
}
//step 2 回调onLoadingStarted
if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
&& canNotifyStatusChanged()) {
target.onLoadStarted(getPlaceholderDrawable());
}
}
@Override
public void onSizeReady(int width, int height) {
//step 3 获取target尺寸成功,调用Engine.load开始加载图片
status = Status.RUNNING;
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);
}
//step 4
private void onResourceReady(Resource resource, R result, DataSource dataSource) {
// We must call isFirstReadyResource before setting status.
boolean isFirstResource = isFirstReadyResource();
status = Status.COMPLETE;
this.resource = resource;
...
Transition super R> animation = animationFactory.build(dataSource, isFirstResource);
target.onResourceReady(result, animation);
notifyLoadSuccess();
}
- step 0
可以看到判断model变量为null,就回调onLoadFailed方法,这个方法就会设置我们配置的error placeholder资源。这里的model变量就是我们通过load(myUrl)方法传入的图片地址。
step 1
判断overrideWidth, overrideHeight是否可用。
如果设置了override(int width, int height) ,直接处理onSizeReady方法逻辑;如果没有设置override,Glide就会等到系统计算完组件(一般是ImageView组件)宽高后再回调onSizeReady。这两种情况最后都会调用onSizeReady方法。step 2
已经开始了图片的加载,回调设置placeholderDrawable,显示placeHolder占位图。step 3 获取图片尺寸成功,engine.load 开始图片的加载过程
step 4
image加载完成回调。这里是加载、缩放、转换之后的数据,可直接用于UI显示。
3.3、engine.load()
#Engine.java
public LoadStatus load(
GlideContext glideContext,
Object model,
Key signature,
int width,
int height,
Class> resourceClass,
Class transcodeClass,
Priority priority,
DiskCacheStrategy diskCacheStrategy,
Map, Transformation>> transformations,
boolean isTransformationRequired,
boolean isScaleOnlyOrNoTransform,
Options options,
boolean isMemoryCacheable,
boolean useUnlimitedSourceExecutorPool,
boolean useAnimationPool,
boolean onlyRetrieveFromCache,
ResourceCallback cb,
Executor callbackExecutor) {
//(1)生成缓存key
EngineKey key =
keyFactory.buildKey(
model,
signature,
width,
height,
transformations,
resourceClass,
transcodeClass,
options);
//(2)从内存缓存中匹配目标图片资源(又细分为activeResources和cache)
memoryResource = loadFromMemory(key, isMemoryCacheable, startTime);
if (memoryResource == null) {
//(4) 内存缓存未命中,则尝试从磁盘缓存或者网络加载图片
return waitForExistingOrStartNewJob(
glideContext,
model,
signature,
width,
height,
resourceClass,
transcodeClass,
priority,
diskCacheStrategy,
transformations,
isTransformationRequired,
isScaleOnlyOrNoTransform,
options,
isMemoryCacheable,
useUnlimitedSourceExecutorPool,
useAnimationPool,
onlyRetrieveFromCache,
cb,
callbackExecutor,
key,
startTime);
}
}
//(3)若内存缓存命中,则直接返回onResourceReady
cb.onResourceReady(memoryResource, DataSource.MEMORY_CACHE);
}
默认情况下,Glide 会在开始一个新的图片请求之前检查以下多级的缓存:
活动资源 (Active Resources) - 正在显示的资源
内存缓存 (Memory cache) - 显示过的资源
资源类型(Resource) - 被解码、转换后的资源
数据来源 (Data) - 源文件(未处理过)资源
也就是内存缓存+磁盘缓存。
首先engine.load方法 首先会生成EngineKey,然尝试从内存中检索缓存,如注释(2)
先后从Active Resources和Memory cache中检索缓存,若命中,则直接直接回调onResourceReady,如注释(3)
@Nullable
private EngineResource> loadFromMemory(
EngineKey key, boolean isMemoryCacheable, long startTime) {
if (!isMemoryCacheable) {
return null;
}
EngineResource> active = loadFromActiveResources(key);
if (active != null) {
return active;
}
EngineResource> cached = loadFromCache(key);
if (cached != null) {
return cached;
}
return null;
}
若内存缓存未命中,则尝试启动解码任务开始解码图片,如注释(4)
private LoadStatus waitForExistingOrStartNewJob(
GlideContext glideContext,
Object model,
Key signature,
int width,
int height,
Class> resourceClass,
Class transcodeClass,
Priority priority,
DiskCacheStrategy diskCacheStrategy,
Map, Transformation>> transformations,
boolean isTransformationRequired,
boolean isScaleOnlyOrNoTransform,
Options options,
boolean isMemoryCacheable,
boolean useUnlimitedSourceExecutorPool,
boolean useAnimationPool,
boolean onlyRetrieveFromCache,
ResourceCallback cb,
Executor callbackExecutor,
EngineKey key,
long startTime) {
//创建EngineJob,EngineJob是一个Runnable
EngineJob engineJob =
engineJobFactory.build(
key,
isMemoryCacheable,
useUnlimitedSourceExecutorPool,
useAnimationPool,
onlyRetrieveFromCache);
//创建DecodeJob
DecodeJob decodeJob =
decodeJobFactory.build(
glideContext,
model,
key,
signature,
width,
height,
resourceClass,
transcodeClass,
priority,
diskCacheStrategy,
transformations,
isTransformationRequired,
isScaleOnlyOrNoTransform,
onlyRetrieveFromCache,
options,
engineJob);
jobs.put(key, engineJob);
engineJob.addCallback(cb, callbackExecutor);
//启动decodeJob
engineJob.start(decodeJob);
return new LoadStatus(cb, engineJob);
}
DecodeJob是整个流程中的重点,我们重点看EngineJob做了哪些事情
//执行EngineJob的start方法
//start方法就是根据diskCacheStrategy策略获取一个executor来执行DecodeJob
public void start(DecodeJob decodeJob) {
this.decodeJob = decodeJob;
//这里根据缓存策略,决定使用哪个Executor。默认情况返回diskCacheExecutor。
//共三种执行器:diskCacheExecutor、sourceExecutor、sourceUnlimitedExecutor对应文章前面给出的流程图。
GlideExecutor executor = decodeJob.willDecodeFromCache()
? diskCacheExecutor
: getActiveSourceExecutor();
executor.execute(decodeJob);
}
//当然,DecodeJob实现了Runnable接口。直接来看它的run方法。
@Override
public void run() {
runWrapped();//看这里!
}
//接着看runWrapped方法。
//RunReason是一个枚举,默认值为INITIALIZE。区分任务目的。
private void runWrapped() {
switch (runReason) {
case INITIALIZE:
stage = getNextStage(Stage.INITIALIZE);
currentGenerator = getNextGenerator();
runGenerators();
break;
case SWITCH_TO_SOURCE_SERVICE:
runGenerators();
break;
case DECODE_DATA:
decodeFromRetrievedData();
break;
default:
throw new IllegalStateException("Unrecognized run reason: " + runReason);
}
}
//获取任务执行阶段:初始化、读取转换后的缓存、读取原文件缓存、原文件加载、结束状态。
private Stage getNextStage(Stage current) {
switch (current) {
case INITIALIZE:
return diskCacheStrategy.decodeCachedResource()
? Stage.RESOURCE_CACHE : getNextStage(Stage.RESOURCE_CACHE);
case RESOURCE_CACHE:
return diskCacheStrategy.decodeCachedData()
? Stage.DATA_CACHE : getNextStage(Stage.DATA_CACHE);
case DATA_CACHE:
// Skip loading from source if the user opted to only retrieve the resource from cache.
return onlyRetrieveFromCache ? Stage.FINISHED : Stage.SOURCE;
case SOURCE:
case FINISHED:
return Stage.FINISHED;
default:
throw new IllegalArgumentException("Unrecognized stage: " + current);
}
}
//根据上一个方法确定的stage,创建对应的Generator(可把它简单理解成资源加载器)
private DataFetcherGenerator getNextGenerator() {
switch (stage) {
case RESOURCE_CACHE:
//从转换后的缓存中读取文件
return new ResourceCacheGenerator(decodeHelper, this);
case DATA_CACHE:
//从原文件缓存中读取文件
return new DataCacheGenerator(decodeHelper, this);
case SOURCE:
//没有缓存,重新加载资源(比如:网络图片、本地文件)
return new SourceGenerator(decodeHelper, this);
case FINISHED:
return null;
default:
throw new IllegalStateException("Unrecognized stage: " + stage);
}
}
//这里开始加载执行
private void runGenerators() {
currentThread = Thread.currentThread();
startFetchTime = LogTime.getLogTime();
boolean isStarted = false;
//这里Generator.startNext()方法中就是加载过程,如果成功加载则返回true并跳出循环,否则切换Generator继续执行。
while (!isCancelled && currentGenerator != null
&& !(isStarted = currentGenerator.startNext())) {
stage = getNextStage(stage);
currentGenerator = getNextGenerator();
//如果任务执行到去加载资源(也就是没有命中磁盘缓存),且切换任务执行环境
if (stage == Stage.SOURCE) {
reschedule();
return;
}
}
// We've run out of stages and generators, give up.
if ((stage == Stage.FINISHED || isCancelled) && !isStarted) {
notifyFailed();
}
// Otherwise a generator started a new load and we expect to be called back in
// onDataFetcherReady.
}
@Override
public void reschedule() {
//更改执行目标为:SOURCE服务。当然也只有在stage == Stage.SOURCE的情况下会被调用。
runReason = RunReason.SWITCH_TO_SOURCE_SERVICE;
callback.reschedule(this);//这里callback正是EngineJob。
}
//代码跟进EngineJob类中,可以看到实现方法。
@Override
public void reschedule(DecodeJob> job) {
// 可以看到,这里获取的SourceExecutor来执行decodeJob。
//也就巧妙地将此decodeJob任务从cacheExecutor切换到了SourceExecutor,这样分工协作更加高效。
getActiveSourceExecutor().execute(job);
}
从最开始没有命中内存缓存开始,然后执行Engine的start方法,默认情况会获取到cacheExecutor执行器来执行decodeJob任务;继续decodeJob的run方法,因为RunReason==INITIALIZE,接着获取stage,默认会返回Stage.RESOURCE_CACHE,这时通过getNextGenerator就返回了ResourceCacheGenerator加载器,紧接着就是调用 ResourceCacheGenerator的startNext方法 ,从转换后的缓存中读取已缓存的资源,如果命中则结束任务并回调结果,反之,任务切换到DataCacheGenerator加载器继续执行,若还是未命中,则切换到SourceGenerator加载器(第一次加载,由于没有任何缓存,就会走到这里),这时会通过任务调度,将线程运行环境切换到 SourceExecutor执行器来执行,最后,待SourceGenerator加载完成后结束任务,回调结果,流程结束。
参考文章
https://www.jianshu.com/p/7c72e040087c