Glide 依赖
implementation 'com.github.bumptech.glide:glide:4.9.0'
Glide 使用方式
Glide.with(context)
.load(url)
.into(view);
Glide -> with
//Context
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
//Activity
public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
//FragmentActivity
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
//Fragment
public static RequestManager with(@NonNull Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
//android.app.Fragment
public static RequestManager with(@NonNull android.app.Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
//View
public static RequestManager with(@NonNull View view) {
return getRetriever(view.getContext()).get(view);
}
with 方法是一个重载方法,但最终都会调用 getRetriever 方法。
getRetriever
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
// Context could be null for other reasons (ie the user passes in null), but in practice it will
// only occur due to errors with the Fragment lifecycle.
Preconditions.checkNotNull(
context,
"You cannot start a load on a not yet attached View or a Fragment where getActivity() "
+ "returns null (which usually occurs when getActivity() is called before the Fragment "
+ "is attached or after the Fragment is destroyed).");
return Glide.get(context).getRequestManagerRetriever();
}
public static Glide get(@NonNull Context context) {
if (glide == null) {
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context);
}
}
}
return glide;
}
Glide 的创建使用的是双重检索( DCL )单例,然后通过 getRequestManagerRetriever 方法获取 RequestManagerRetriever 对象。
RequestManagerRetriever.get
//Context
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) {
return get(((ContextWrapper) context).getBaseContext());
}
}
return getApplicationManager(context);
}
get 方法也是一个重载方法,这里就不全部罗列了。看起来处理比较多,而实际上只处理了两种情况的参数。
一种为「 非 Application 」类型的参数,一种为「 Application 」类型的参数。
getApplicationManager
private RequestManager getApplicationManager(@NonNull Context context) {
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.
// TODO(b/27524013): Factor out this Glide.get() call.
Glide glide = Glide.get(context.getApplicationContext());
applicationManager =
factory.build(
glide,
new ApplicationLifecycle(),
new EmptyRequestManagerTreeNode(),
context.getApplicationContext());
}
}
}
return applicationManager;
}
ApplicationLifecycle
class ApplicationLifecycle implements Lifecycle {
@Override
public void addListener(@NonNull LifecycleListener listener) {
listener.onStart();
}
@Override
public void removeListener(@NonNull LifecycleListener listener) {
// Do nothing.
}
}
当参数为 Application 类型的参数时,会创建一个 ApplicationLifecycle 对象,此时 Glide 的生命周期就和 Application 生命周期一致。
RequestManagerRetriever.get
public RequestManager get(@NonNull FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
//通过当前 activity 获取 FragmentManager
//用于创建透明 fragment
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(
activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
supportFragmentGet
private RequestManager supportFragmentGet(
@NonNull Context context,
@NonNull FragmentManager fm,
@Nullable Fragment parentHint,
boolean isParentVisible) {
//创建透明的 fragment
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);
//将 Glide 生命周期与 fragment 绑定
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
getSupportRequestManagerFragment
private SupportRequestManagerFragment getSupportRequestManagerFragment(
@NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
//通过 TAG 查找 fragment
SupportRequestManagerFragment current =
(SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
//通过 FragmentManager 查找 fragment
current = pendingSupportRequestManagerFragments.get(fm);
//如果为空则创建一个 fragment 并加入缓存
if (current == null) {
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;
}
SupportRequestManagerFragment
public class SupportRequestManagerFragment extends Fragment {
...
@Override
public void onStart() {
super.onStart();
lifecycle.onStart();
}
@Override
public void onStop() {
super.onStop();
lifecycle.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
lifecycle.onDestroy();
unregisterFragmentWithRoot();
}
...
}
当参数为非 Application 类型的参数时,会创建一个 ActivityFragmentLifecycle 对象,此时 Glide 的生命周期就和 Fragment 生命周期一致。
最终 Glide.with() 方法会返回一个 RequestManager 对象。
RequestManager -> load
public RequestBuilder load(@Nullable Bitmap bitmap) {
return asDrawable().load(bitmap);
}
public RequestBuilder load(@Nullable Drawable drawable) {
return asDrawable().load(drawable);
}
public RequestBuilder load(@Nullable String string) {
return asDrawable().load(string);
}
public RequestBuilder load(@Nullable Uri uri) {
return asDrawable().load(uri);
}
public RequestBuilder load(@Nullable File file) {
return asDrawable().load(file);
}
public RequestBuilder load(@RawRes @DrawableRes @Nullable Integer resourceId) {
return asDrawable().load(resourceId);
}
public RequestBuilder load(@Nullable URL url) {
return asDrawable().load(url);
}
public RequestBuilder load(@Nullable byte[] model) {
return asDrawable().load(model);
}
public RequestBuilder load(@Nullable Object model) {
return asDrawable().load(model);
}
asDrawable
public RequestBuilder asDrawable() {
return as(Drawable.class);
}
public RequestBuilder as(
@NonNull Class resourceClass) {
return new RequestBuilder<>(glide, this, resourceClass, context);
}
asDrawable 方法其实是创建一个 RequestBuilder 对象
load
public RequestBuilder load(@Nullable URL url) {
return loadGeneric(url);
}
loadGeneric
private RequestBuilder loadGeneric(@Nullable Object model) {
this.model = model;
isModelSet = true;
return this;
}
load 方法流程比较简单,首先会创建一个 RequestBuilder 对象,然后将传入的资源赋值给 RequestBuilder 对象中的 model。
RequestBuilder -> into
public ViewTarget into(@NonNull ImageView view) {
...
return into(
glideContext.buildImageViewTarget(view, transcodeClass),
/*targetListener=*/ null,
requestOptions,
Executors.mainThreadExecutor());
}
into
private > Y into(
@NonNull Y target,
@Nullable RequestListener targetListener,
BaseRequestOptions> options,
Executor callbackExecutor) {
...
requestManager.track(target, request);
...
}
track
synchronized void track(@NonNull Target> target, @NonNull Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);
}
runRequest
public void runRequest(@NonNull Request 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);
}
}
在 RequestTracker 中维护了两种队列 : requests 执行队列、pendingRequests 等待队列。( Okhttp 中也有类似的队列,同步异步的执行就绪队列 )
所以我们知道 into 方法最终会执行 request,那么是谁去维护处理这 2 个队列呢?
根据方法倒推
- runRequest 方法在 RequestTracker 类中
RequestTracker -> runRequest - track 方法执行了 runRequest 方法
RequestManager -> track - RequestManager 对象中持有 RequestTracker 对象
RequestManager
所以我们重点看 RequestManager 对象
RequestManager
public class RequestManager implements LifecycleListener,
ModelTypes> {
...
public synchronized void onStart() {
resumeRequests();
targetTracker.onStart();
}
public synchronized void onStop() {
pauseRequests();
targetTracker.onStop();
}
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);
}
...
}
回到之前 with 方法中添加的透明 Fragment
SupportRequestManagerFragment
public class SupportRequestManagerFragment extends Fragment {
...
@Override
public void onStart() {
super.onStart();
lifecycle.onStart();
}
@Override
public void onStop() {
super.onStop();
lifecycle.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
lifecycle.onDestroy();
unregisterFragmentWithRoot();
}
...
}
在页面执行 onStart 方法时会触发 lifecycle.onStart 方法,lifecycle.onStart 则会出发 RequestManager 的 onStart 方法
RequestManager -> onStart
public synchronized void onStart() {
resumeRequests();
targetTracker.onStart();
}
resumeRequests
public synchronized void resumeRequests() {
requestTracker.resumeRequests();
}
resumeRequests
public void resumeRequests() {
isPaused = false;
for (Request request : Util.getSnapshot(requests)) {
// We don't need to check for cleared here. Any explicit clear by a user will remove the
// Request from the tracker, so the only way we'd find a cleared request here is if we cleared
// it. As a result it should be safe for us to resume cleared requests.
if (!request.isComplete() && !request.isRunning()) {
request.begin();
}
}
pendingRequests.clear();
}
所以可以想到,当 Activity 显示时会便利 request 执行队列,当 Activity 不可见时会将 request 加入到 pendingRequests 等待队列
总结
- with
- 通过单例创建 Glide 对象
- 当参数类型为 Application 时, Glide 生命周期与 Application 一致;当参数类型为非 Application 时,会创建一个透明的 Fragment,Glide 生命周期与 Fragment 一致
- 最终返回一个 RequestManager 对象
- load
- 创建一个 RequestBuilder 对象
- 将传入的资源赋值给 RequestBuilder 对象中的 model 并返回
- into
- 执行 request
- 根据生命周期处理 request