Glide源码分析(一) ------整体流程分析
源码分析基于Glide 4.3.0
implementation group: 'com.github.bumptech.glide', name: 'glide', version: '4.3.0'
1、整体流程
一般地,在Activity中Glide可以通过下面代码将链接为url的图片加载到imageView
Glide.with(activity)
.load(url)
.into(imageView);
下面具体分析三个方法执行流程(如果with、load、into参数不同,执行过程也有不同)
1.1、with 流程:返回RequestManager对象
其中Glide.with接收Activity、Context、Fragment等类型的参数,返回一个RequestManager对象:
public static RequestManager with(Context context) {
return getRetriever(context).get(context);
}
public static RequestManager with(Activity activity) {
return getRetriever(activity).get(activity);
}
public static RequestManager with(FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
public static RequestManager with(android.app.Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
public static RequestManager with(Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
public static RequestManager with(View view) {
return getRetriever(view.getContext()).get(view);
}
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
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(Context context) {
if (glide == null) {
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context);
}
}
}
return glide;
}
private static void checkAndInitializeGlide(Context context) {
if (isInitializing) {
throw new IllegalStateException("You cannot call Glide.get() in registerComponents(),"
+ " use the provided Glide instance instead");
}
isInitializing = true;
initializeGlide(context);
isInitializing = false;
}
private static void initializeGlide(Context context) {
Context applicationContext = context.getApplicationContext();
GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();
List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
manifestModules = new ManifestParser(applicationContext).parse();
}
if (annotationGeneratedModule != null
&& !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {
Set<Class<?>> excludedModuleClasses =
annotationGeneratedModule.getExcludedModuleClasses();
Iterator<com.bumptech.glide.module.GlideModule> iterator = manifestModules.iterator();
while (iterator.hasNext()) {
com.bumptech.glide.module.GlideModule current = iterator.next();
if (!excludedModuleClasses.contains(current.getClass())) {
continue;
}
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "AppGlideModule excludes manifest GlideModule: " + current);
}
iterator.remove();
}
}
if (Log.isLoggable(TAG, Log.DEBUG)) {
for (com.bumptech.glide.module.GlideModule glideModule : manifestModules) {
Log.d(TAG, "Discovered GlideModule from manifest: " + glideModule.getClass());
}
}
RequestManagerRetriever.RequestManagerFactory factory =
annotationGeneratedModule != null
? annotationGeneratedModule.getRequestManagerFactory() : null;
GlideBuilder builder = new GlideBuilder()
.setRequestManagerFactory(factory);
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
module.applyOptions(applicationContext, builder);
}
if (annotationGeneratedModule != null) {
annotationGeneratedModule.applyOptions(applicationContext, builder);
}
Glide glide = builder.build(applicationContext);
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
module.registerComponents(applicationContext, glide, glide.registry);
}
if (annotationGeneratedModule != null) {
annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
}
context.getApplicationContext().registerComponentCallbacks(glide);
Glide.glide = glide;
}
从代码中可以看到,Glide.with方法首先调用了getRetriever方法:检查static类型的glide是否已经初始化,如果没有就调用initializeGlide初始化glide,返回glide的requestManagerRetriever属性;然后调用RequestManagerRetriever对象的get方法,返回RequestManager对象。
RequestManagerRetriever类的get方法有几个重载方法:
private RequestManager getApplicationManager(Context context) {
if (applicationManager == null) {
synchronized (this) {
if (applicationManager == null) {
Glide glide = Glide.get(context.getApplicationContext());
applicationManager =
factory.build(
glide,
new ApplicationLifecycle(),
new EmptyRequestManagerTreeNode(),
context.getApplicationContext());
}
}
}
return applicationManager;
}
public RequestManager get(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);
}
public RequestManager get(FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm, null);
}
}
public RequestManager get(Fragment fragment) {
Preconditions.checkNotNull(fragment.getActivity(),
"You cannot start a load on a fragment before it is attached or after it is destroyed");
if (Util.isOnBackgroundThread()) {
return get(fragment.getActivity().getApplicationContext());
} else {
FragmentManager fm = fragment.getChildFragmentManager();
return supportFragmentGet(fragment.getActivity(), fm, fragment);
}
}
public RequestManager get(Activity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
android.app.FragmentManager fm = activity.getFragmentManager();
return fragmentGet(activity, fm, null);
}
}
public RequestManager get(View view) {
if (Util.isOnBackgroundThread()) {
return get(view.getContext().getApplicationContext());
}
Preconditions.checkNotNull(view);
Preconditions.checkNotNull(view.getContext(),
"Unable to obtain a request manager for a view without a Context");
Activity activity = findActivity(view.getContext());
if (activity == null) {
return get(view.getContext().getApplicationContext());
}
if (activity instanceof FragmentActivity) {
Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
return fragment != null ? get(fragment) : get(activity);
}
android.app.Fragment fragment = findFragment(view, activity);
if (fragment == null) {
return get(activity);
}
return get(fragment);
}
private RequestManager fragmentGet(Context context, android.app.FragmentManager fm,
android.app.Fragment parentHint) {
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
RequestManagerFragment getRequestManagerFragment(
final android.app.FragmentManager fm, android.app.Fragment parentHint) {
RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = pendingRequestManagerFragments.get(fm);
if (current == null) {
current = new RequestManagerFragment();
current.setParentFragmentHint(parentHint);
pendingRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
主要逻辑如下:
(1)get方法参数为Activity对象时:Util.isOnBackgroundThread()为true表示在非主线程,然后依次调用get(activity.getApplicationContext()) -> get(context) -> getApplicationManager(context) , 检查applicationManager是否为null,为null则创建并传入ApplicationLifecycle对象,由于glide对象只会初始化一次,内部的requestManagerRetriever也只有一个,于是applicationManager也只有一个;Util.isOnBackgroundThread()为false表示在主线程,调用fragmentGet方法创建RequestManager对象:查找已经存在的RequestManagerFragment实例,不存在则创建,于是获取到current,如果current的requestManager对象为null,则根据glide、current.getGlideLifecycle()等参数创建RequestManager对象。(2) get方法参数为Fragment、fragmentActivity时逻辑类似。
上述逻辑可总结为:如果get参数为Application对象或者在非主线程,则创建applicationManager,静态变量glide持有requestManagerRetriever对象,requestManagerRetriever对象持有applicationManager;如果在主线程且get参数为Activity、Fragment、FragmentActivity,则创建并复用相关联的RequestManagerFragment,内部持有RequestManager。
1.2、load 流程:返回RequestBuilder<Drawable>对象
RequestManager中load方法如下,首先调用自身的asDrawable()方法,表明数据解析类是com.bumptech.glide.load.ResourceDecoder接口的子类,解析结果是Drawable类的子类实例,例如BitmapDrawable、GifDrawable等。
/**
* Attempts to always load the resource using any registered {@link
* com.bumptech.glide.load.ResourceDecoder}s that can decode any subclass of {@link Drawable}.
*
* <p> By default, may return either a {@link android.graphics.drawable.BitmapDrawable} or {@link
* GifDrawable}, but if additional decoders are registered for other {@link Drawable} subclasses,
* any of those subclasses may also be returned. </p>
*
* @return A new request builder for loading a {@link Drawable}.
*/
public RequestBuilder<Drawable> asDrawable() {
return as(Drawable.class);
}
@CheckResult
public RequestBuilder<Drawable> load(@Nullable Object model) {
return asDrawable().load(model);
}
RequestBuilder的load方法如下,仅仅是设置图片的数据源:
public RequestBuilder<TranscodeType> load(@Nullable Object model) {
return loadGeneric(model);
}
private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
this.model = model;
isModelSet = true;
return this;
}
1.3、into 流程:返回Target<Drawable>对象
RequestManager执行load方法以后,得到一个RequestBuilder<Drawable>对象,再执行into方法,将图片加载到ImageView,into方法如下:
public Target<TranscodeType> into(ImageView view) {
Util.assertMainThread();
Preconditions.checkNotNull(view);
RequestOptions requestOptions = this.requestOptions;
...
return into(glideContext.buildImageViewTarget(view, transcodeClass), null, requestOptions);
}
private <Y extends Target<TranscodeType>> Y into(
@NonNull Y target,
@Nullable RequestListener<TranscodeType> targetListener,
RequestOptions options) {
Util.assertMainThread();
Preconditions.checkNotNull(target);
if (!isModelSet) {
throw new IllegalArgumentException("You must call #load() before calling #into()");
}
options = options.autoClone();
Request request = buildRequest(target, targetListener, 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;
}
主要逻辑是:glideContext.buildImageViewTarget(view, transcodeClass)构建一个Target<Drawable>对象,执行下面一个into方法,首先根据请求参数等构建一个请求request,然后获取之前的请求previous(1)如果两个请求等同,则回收request,如果previous不在运行中,则执行previous.begin()进行请求(2)如果两个请求不等同,则将request添加到target中,然后执行requestManager.track(target, request)。
RequestManager的track方法如下:
void track(Target<?> target, Request request) {
targetTracker.track(target);
requestTracker.runRequest(request);
}
RequestTracker中track方法如下:
public void runRequest(Request request) {
requests.add(request);
if (!isPaused) {
request.begin();
} else {
pendingRequests.add(request);
}
}
RequestManager中track方法中requestTracker的runRequest方法执行请求,或者将request添加到集合中等待执行请求。
2、生命周期
Glide能够根据Fragment以及Activity生命周期来启动以及暂停请求,具体如何实现的呢?
首先看RequestTracker中相关代码:
public void runRequest(Request request) {
requests.add(request);
if (!isPaused) {
request.begin();
} else {
pendingRequests.add(request);
}
}
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();
}
public void restartRequests() {
for (Request request : Util.getSnapshot(requests)) {
if (!request.isComplete() && !request.isCancelled()) {
request.pause();
if (!isPaused) {
request.begin();
} else {
pendingRequests.add(request);
}
}
}
}
RequestTracker中isPaused标识位用来标识pendingRequests中Request执行状态,还控制runRequest中请求是直接执行还是添加到集合中,pauseRequests、resumeRequests、restartRequests三个方法分别表示pause、resume、restart请求。搜索RequestTracker中resumeRequests方法调用,其被RequestManager的resumeRequests方法调用,在RequestManager的onStart方法中又调用了resumeRequests方法。
public void resumeRequests() {
Util.assertMainThread();
requestTracker.resumeRequests();
}
public void resumeRequestsRecursive() {
Util.assertMainThread();
resumeRequests();
for (RequestManager requestManager : treeNode.getDescendants()) {
requestManager.resumeRequests();
}
}
@Override
public void onStart() {
resumeRequests();
targetTracker.onStart();
}
2.1、主线程中with参数为Activity时执行流程
开启调试,在RequestManager中打断点,在主线程执行Glide.with(activity).load(url).into(imageView)方法, 调用堆栈如下:
于是调用流程如下: Activity.performStart() -> RequestManagerFragment.onStart() -> ActivityFragmentLifecycler.onStart() -> RequestManager.onStart() -> RequestManager.resumeRequests(),Activity执行performStart()时会执行onStart方法,同时也会调用相关联fragments的onStart()方法, 此时Request执行begin()方法。
RequestManagerFragment执行onStart()、onStop()、onDestory()时对应地执行lifecycle的onStart()、onStop()、onDestroy()方法,lifecycle是ActivityFragmentLifecycle的实例,相关代码如下:
class ActivityFragmentLifecycle implements Lifecycle {
private final Set<LifecycleListener> lifecycleListeners =
Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
private boolean isStarted;
private boolean isDestroyed;
@Override
public void addListener(LifecycleListener listener) {
lifecycleListeners.add(listener);
if (isDestroyed) {
listener.onDestroy();
} else if (isStarted) {
listener.onStart();
} else {
listener.onStop();
}
}
@Override
public void removeListener(LifecycleListener listener) {
lifecycleListeners.remove(listener);
}
void onStart() {
isStarted = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart();
}
}
void onStop() {
isStarted = false;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStop();
}
}
void onDestroy() {
isDestroyed = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onDestroy();
}
}
}
在RequestManager创建时自身作为LifecycleListener接口的实现,执行lifecycle.addListener添加到RequestManagerFragment的lifecycle中:
public RequestManager(
Glide glide, Lifecycle lifecycle, RequestManagerTreeNode treeNode, Context context) {
this(glide, lifecycle, treeNode, new RequestTracker(), glide.getConnectivityMonitorFactory(),
context);
}
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;
connectivityMonitor =
factory.build(
context.getApplicationContext(),
new RequestManagerConnectivityListener(requestTracker));
if (Util.isOnBackgroundThread()) {
mainHandler.post(addSelfToLifecycle);
} else {
lifecycle.addListener(this);
}
lifecycle.addListener(connectivityMonitor);
setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
glide.registerRequestManager(this);
}
于是RequestManagerFragment的生命周期先传递lifecycle,再传递到RequestManager,于是其在RequestManagerFragment执行onStart()方法时resume请求,onPause()方法时pause请求,onDestory()时clear请求。
2.2、主线程中with参数为Application类型的context时执行流程
with参数为Application时,static类型的Glide实例中的requestManagerRetriever中的applicationManager属性创建时的lifecycle对应ApplicationLifecycle,代码如下:
class ApplicationLifecycle implements Lifecycle {
@Override
public void addListener(LifecycleListener listener) {
listener.onStart();
}
@Override
public void removeListener(LifecycleListener listener) {
}
}
RequestManager只有添加到lifecycle中时才会执行onStart()方法,onPause()方法以及onDestroy()方法不会执行,也就不能根据fragment以及activity的生命周期管理请求了。
在子线程中Glide.with(activity)等会使用Application类型的context,其余流程和当前相同。
3、总结
本文分析了Glide的主要执行流程,以及Glide如何管理fragment和activity这种具有生命周期组件内的请求。