阅读源码技巧:抽丝剥茧、点到为止。应该认准一个功能点,然后去分析这个功能点是如何实现的。但只要去追寻主体的实现逻辑即可,千万不要试图去搞懂每一行代码都是什么意思,那样很容易陷入思维黑洞当中,而且越陷越深。因为这些庞大的系统都不是一个人写出来的,每一行代码都想搞明白,就会感觉自己是在盲人摸象,永远也研究不透。如果只是去分析主体的实现逻辑,那么就比较明确的目的性,阅读源码会更加轻松,也更加有成效。
这篇主要是将以下代码搞明白是如何实现将一张网络图片展示到ImageView上面的,将Glide的一整套图片加载机制记得基本流程梳理:
Glide.with(this).load(url).into(imageView);
总体设计
1、with()
with()方法主要用于创建RequestManager,Glide是通过Activity/Fragment生命周期管理Request,流程图如下:
从with()方法入手,with方法传入的参数可以是context、Activity、Fragment或FragmentActivity,以FragmentActivity为例子:
public static RequestManager with(FragmentActivity activity) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(activity);
}
获取了RequestManagerRetriever,并调用了其get方法:
public RequestManager get(FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm);
}
}
判断是否在主线程中调用,如果是子线程中,则调用 get(activity.getApplicationContext()):
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);
}
很明显传入的context是ApplicationContext,所以会调用getApplicationManager(context):
private RequestManager getApplicationManager(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.
applicationManager = new RequestManager(context.getApplicationContext(),
new ApplicationLifecycle(), new EmptyRequestManagerTreeNode());
}
}
}
return applicationManager;
}
创建了一个RequestManager,并将其返回,这里的ApplicationLifecycle很重要,后面会提到,再回到之前的get方法:
public RequestManager get(FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(activity, fm);
}
}
如果在主线程中调用get方法,则会通过获取传入activity的FragementManager,并将其传入到supportFragementGet(activity,fm)方法中:
RequestManager supportFragmentGet(Context context, FragmentManager fm) {
SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
current.setRequestManager(requestManager);
}
return requestManager;
}
首先是调用getSupportRequestManagerFragment方法获取一个SupportRequestManagerFragment,SupportRequestManagerFragment是一个无界面的Fragement类,起到把请求和Activity生命周期同步的作用:
SupportRequestManagerFragment getSupportRequestManagerFragment(final FragmentManager fm) {
SupportRequestManagerFragment current = (SupportRequestManagerFragment) fm.findFragmentByTag(
FRAGMENT_TAG);
if (current == null) {
current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
current = new SupportRequestManagerFragment();
pendingSupportRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
可以看到getSupportRequestManagerFragment中,会先去判断传入的FragmentManager中是否已经绑定了这个SupportRequestManagerFragment,没有就将其创建并,并添加到FragmentManager中。
可以看到SupportRequestManagerFragment中生命周期的方法,都会同步调用lifecycle的相应方法:
@Override
public void onStart() {
super.onStart();
lifecycle.onStart();
}
@Override
public void onStop() {
super.onStop();
lifecycle.onStop();
}
而这个lifecycle就是ActivityFragmentLifecycle,它将用了观察者模式,可以发现addListener就是添加观察者,然后每一个生命周期方法,同步给 每一个listener:
@Override
public void addListener(LifecycleListener listener) {
lifecycleListeners.add(listener);
if (isDestroyed) {
listener.onDestroy();
} else if (isStarted) {
listener.onStart();
} else {
listener.onStop();
}
}
void onStart() {
isStarted = true;
for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
lifecycleListener.onStart();
}
}
回到supportFragmentGet方法中:
RequestManager supportFragmentGet(Context context, FragmentManager fm) {
SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
requestManager = new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
current.setRequestManager(requestManager);
}
return requestManager;
}
接下来就是获取SupportRequestManagerFragment中的RequestManager中的RequestManager,判断其是否存在,不在则进行创建,然后和SupportRequestManagerFragment进行绑定,这里需要强调的是,构建RequestManager时,将SupportRequestManagerFragment的lifecycle传入,下面是RequestManager构造函数:
RequestManager(Context context, final Lifecycle lifecycle, RequestManagerTreeNode treeNode,
RequestTracker requestTracker, ConnectivityMonitorFactory factory) {
this.context = context.getApplicationContext();
this.lifecycle = lifecycle;
this.treeNode = treeNode;
this.requestTracker = requestTracker;
this.glide = Glide.get(context);
this.optionsApplier = new OptionsApplier();
ConnectivityMonitor connectivityMonitor = factory.build(context,
new RequestManagerConnectivityListener(requestTracker));
// If we're the application level request manager, we may be created on a background thread. In that case we
// cannot risk synchronously pausing or resuming requests, so we hack around the issue by delaying adding
// ourselves as a lifecycle listener by posting to the main thread. This should be entirely safe.
if (Util.isOnBackgroundThread()) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
lifecycle.addListener(RequestManager.this);
}
});
} else {
lifecycle.addListener(this);
}
lifecycle.addListener(connectivityMonitor);
}
可以发现,lifecycle.addListener方法,将RequestManager自身添加到lifecycle中,这里巧妙之处在于,SupportRequestManagerFragement的生命周期方法,都会同步通知lifecycle的所有Listener,所以SupportRequestManagerFragement的生命周期都可同步通知RequestManager。
上面还做了判断,如果这个RequestManager是application级别的,将其post到主线程,再调用lifecycle.addListener(RequestManager.this)方法,保证生命周期的同步效果。
总结:通过with()方法中的参数不同,调用RequestManagerRetriever的get方法,最终创建一个空的Fragement名为SupportRequestManagerFragment并绑定一个RequestManager。
2、load()
with()方法返回的是一个RequestManager,那么load()方法逻辑就是在RequestManager中。
load()调用处理流程图:
public DrawableTypeRequest<String> load(String string) {
return (DrawableTypeRequest<String>) fromString().load(string);
}
会先调用fromString在调用load方法:
public DrawableTypeRequest<String> fromString() {
return loadGeneric(String.class);
}
private <T> DrawableTypeRequest<T> loadGeneric(Class<T> modelClass) {
ModelLoader<T, InputStream> streamModelLoader = Glide.buildStreamModelLoader(modelClass, context);
ModelLoader<T, ParcelFileDescriptor> fileDescriptorModelLoader =
Glide.buildFileDescriptorModelLoader(modelClass, context);
if (modelClass != null && streamModelLoader == null && fileDescriptorModelLoader == null) {
throw new IllegalArgumentException("Unknown type " + modelClass + ". You must provide a Model of a type for"
+ " which there is a registered ModelLoader, if you are using a custom model, you must first call"
+ " Glide#register with a ModelLoaderFactory for your custom model class");
}
return optionsApplier.apply(
new DrawableTypeRequest<T>(modelClass, streamModelLoader, fileDescriptorModelLoader, context,
glide, requestTracker, lifecycle, optionsApplier));
}
loadGeneric方法中创建了两个ModeLoader,分别是streamModelLoader和fileDescriptorModelLoader,然后通过它们构造一个DrawableTypeRequest。
其实就是通过工厂模式创建相应类型的ModeLoader,以 Glide.buildStreamModelLoader为例:
public static <T> ModelLoader<T, InputStream> buildStreamModelLoader(Class<T> modelClass, Context context) {
return buildModelLoader(modelClass, InputStream.class, context);
}
这里传递了InputStream.class:
public static <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass,
Context context) {
if (modelClass == null) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Unable to load null model, setting placeholder only");
}
return null;
}
return Glide.get(context).getLoaderFactory().buildModelLoader(modelClass, resourceClass);
}
通过Glide.get(context).getLoaderFactory()获取GenericLoaderFactory()并调用buildModelLoader创建InputStream.class对应的ModelLoader:
public synchronized <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass) {
ModelLoader<T, Y> result = getCachedLoader(modelClass, resourceClass);
if (result != null) {
// We've already tried to create a model loader and can't with the currently registered set of factories,
// but we can't use null to demonstrate that failure because model loaders that haven't been requested
// yet will be null in the cache. To avoid this, we use a special signal model loader.
if (NULL_MODEL_LOADER.equals(result)) {
return null;
} else {
return result;
}
}
final ModelLoaderFactory<T, Y> factory = getFactory(modelClass, resourceClass);
if (factory != null) {
result = factory.build(context, this);
cacheModelLoader(modelClass, resourceClass, result);
} else {
// We can't generate a model loader for the given arguments with the currently registered set of factories.
cacheNullLoader(modelClass, resourceClass);
}
return result;
}
getCachedLoader方法判断InputStream.class对应的ModelLoader是否已经创建过,也就是是否存在内存缓存中,有则返回。
然后调用了getFactory方法,根据InputStream.class,创建其对应的ModelLoaderFactory:
private <T, Y> ModelLoaderFactory<T, Y> getFactory(Class<T> modelClass, Class<Y> resourceClass) {
Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> resourceToFactories = modelClassToResourceFactories.get(modelClass);
ModelLoaderFactory/*T, Y*/ result = null;
if (resourceToFactories != null) {
result = resourceToFactories.get(resourceClass);
}
if (result == null) {
for (Class<? super T> registeredModelClass : modelClassToResourceFactories.keySet()) {
// This accounts for model subclasses, our map only works for exact matches. We should however still
// match a subclass of a model with a factory for a super class of that model if if there isn't a
// factory for that particular subclass. Uris are a great example of when this happens, most uris
// are actually subclasses for Uri, but we'd generally rather load them all with the same factory rather
// than trying to register for each subclass individually.
if (registeredModelClass.isAssignableFrom(modelClass)) {
Map<Class/*Y*/, ModelLoaderFactory/*T, Y*/> currentResourceToFactories =
modelClassToResourceFactories.get(registeredModelClass);
if (currentResourceToFactories != null) {
result = currentResourceToFactories.get(resourceClass);
if (result != null) {
break;
}
}
}
}
}
return result;
}