简述
Glide为Android平台下的图片加载框架,它的使用方法可以查看教程文档。
这里从一个最简单的使用实例入手,分析glide源码调用过程(使用的glide版本为v4.8.0):
Glide.with(activity)
.load(imgUrl)
.into(imageView);
本例实现了在一个FragmentActivity中,加载远程图片,显示在imageview视图上。图片加载过程大致可以分为三步:
- with: 预备开启一个加载,并与当前Activity生命周期绑定;
- load:设置数据源,构建请求的参数;
- into:创建请求,开始真正的加载图片,最终显示在视图上。
接下来从第一步with方法开始,看看源码中做了什么操作。
源码分析
with方法中主要做了两件事,一是初始化Glide对象,二是返回合适的RequestManager对象。
Glide初始化
在Glide类中,有多个with方法的重载实现,最终都是返回RequestManager对象,(RequestManager负责管理发起的加载Request),如图:
简单概括它们的作用是当传入的上下文为FragmentActivity或者可以取到FragmentActivity时,可以将本次加载与FragmentActivity的生命周期进行绑定,其中又分别适配了v4和app的FragmentManager。
在本例中将会调用下面的重载方法:
@NonNull
publicstatic RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
其中getRetriever方法返回RequestManagerRetriever(顾名思义,它负责创建或检索出合适的RequestManager)。
@NonNull
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();
}
看Glide.get(context)方法,返回单例:
@NonNull
public static Glide get(@NonNull Context context) {
if (glide == null) {
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context);
}
}
}
return glide;
}
checkAndInitializeGlide方法中加了一个boolean变量判断避免重复调用初始化,其中又调用initializeGlide方法。
接下来就是Glide的初始化过程:
private static void initializeGlide(@NonNull Context context) {
initializeGlide(context, new GlideBuilder());
}
@SuppressWarnings("deprecation")
privatestatic void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
Context applicationContext = context.getApplicationContext();
// 获取注解生成的自定义的GlideModule,具体使用查看Glide文档「Generated API」说明。
GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();
List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
// 获取在AndroidManifest中注册的GlideModule(Glide V4之前的版本使用)。
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()) {
// 排除不需要的GlideModule(由自己决定)。
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());
}
}
// 获取自定义的RequestManagerFactory,设置给GlideBuilder。
RequestManagerRetriever.RequestManagerFactory factory =
annotationGeneratedModule != null
? annotationGeneratedModule.getRequestManagerFactory() : null;
builder.setRequestManagerFactory(factory);
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
// 可以在自定义的GlideModule中给GlideBuilder设置配置。
module.applyOptions(applicationContext, builder);
}
if (annotationGeneratedModule != null) {
// 可以在自定义的GlideModule中给GlideBuilder设置配置。
annotationGeneratedModule.applyOptions(applicationContext, builder);
}
// 通过GlideBuilder构造了一个Glide对象。
Glide glide = builder.build(applicationContext);
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
// 可以在自定义的GlideModule中给glide中的Registry添加或替换组件。
module.registerComponents(applicationContext, glide, glide.registry);
}
if (annotationGeneratedModule != null) {
// 可以在自定义的GlideModule中给glide中的Registry添加或替换组件。
annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
}
// 注册ComponentCallbacks2用以监听内存使用情况。
applicationContext.registerComponentCallbacks(glide);
Glide.glide = glide;
}
在本例中使用默认的glide配置,没有自定义GlideModule,直接看builder.build(applicationContext)方法:
@NonNull
Glide build(@NonNull Context context) {
// 初始化用于网络操作的线程池。
if (sourceExecutor == null) {
sourceExecutor = GlideExecutor.newSourceExecutor();
}
// 初始化用于磁盘缓存操作的线程池
if (diskCacheExecutor == null) {
diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
}
// 初始化用于动画的线程池
if (animationExecutor == null) {
animationExecutor = GlideExecutor.newAnimationExecutor();
}
// 初始化根据手机设备推荐缓存容器大小的计算辅助工具类
if (memorySizeCalculator == null) {
memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
}
// 初始化生成网络监听广播注册的工厂类,该Factory会根据是否有NETWORK_PERMISSION生成对应的监听器(通常情况下都应该申请)。拥有权限情况下的监听器会注册广播监听CONNECTIVITY_ACTION,当收到联网广播时会触发RequestManager尝试重试请求。
if (connectivityMonitorFactory == null) {
connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
}
// 初始化bitmap缓存容器
if (bitmapPool == null) {
int size = memorySizeCalculator.getBitmapPoolSize();
if (size > 0) {
bitmapPool = new LruBitmapPool(size);
} else {
bitmapPool = new BitmapPoolAdapter();
}
}
// 初始化存储字节数组的缓存容器
if (arrayPool == null) {
arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
}
// 初始化Resource缓存容器
if (memoryCache == null) {
memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
}
// 初始化用于创建磁盘缓存的工厂类
if (diskCacheFactory == null) {
diskCacheFactory = new InternalCacheDiskCacheFactory(context);
}
// 初始化引擎,该对象负责启动加载资源和管理活动和缓存的资源。重要的类,后续加载和处理响应都会经过此类。
if (engine == null) {
engine =
new Engine(
memoryCache,
diskCacheFactory,
diskCacheExecutor,
sourceExecutor,
GlideExecutor.newUnlimitedSourceExecutor(),
GlideExecutor.newAnimationExecutor(),
isActiveResourceRetentionAllowed);
}
// 初始化获取RequestManager的工具类,接下来马上就会用到。
RequestManagerRetriever requestManagerRetriever =
new RequestManagerRetriever(requestManagerFactory);
// 最终创建并返回Glide对象
return new Glide(
context,
engine,
memoryCache,
bitmapPool,
arrayPool,
requestManagerRetriever,
connectivityMonitorFactory,
logLevel,
defaultRequestOptions.lock(),
defaultTransitionOptions);
}
GlideBuilder的build方法中初始化了多个线程池对应不同使用功能,便于不同模块的线程管理,以及缓存容器和Engine、RequestManagerRetriever对象。之后实例化Glide对象并传入各个参数。
接着看Glide的构造方法:
Glide(
@NonNull Context context,
@NonNull Engine engine,
@NonNull MemoryCache memoryCache,
@NonNull BitmapPool bitmapPool,
@NonNull ArrayPool arrayPool,
@NonNull RequestManagerRetriever requestManagerRetriever,
@NonNull ConnectivityMonitorFactory connectivityMonitorFactory,
int logLevel,
@NonNull RequestOptions defaultRequestOptions,
@NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions) {
this.engine = engine;
this.bitmapPool = bitmapPool;
this.arrayPool = arrayPool;
this.memoryCache = memoryCache;
this.requestManagerRetriever = requestManagerRetriever;
this.connectivityMonitorFactory = connectivityMonitorFactory;
DecodeFormat decodeFormat = defaultRequestOptions.getOptions().get(Downsampler.DECODE_FORMAT);
bitmapPreFiller = new BitmapPreFiller(memoryCache, bitmapPool, decodeFormat);
final Resources resources = context.getResources();
registry = new Registry();
// Right now we're only using this parser for HEIF images, which are only supported on OMR1+.
// If we need this for other file types, we should consider removing this restriction.
// Note that order here matters. We want to check the ExifInterface parser first for orientation
// and then fall back to DefaultImageHeaderParser for other fields.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
registry.register(new ExifInterfaceImageHeaderParser());
}
registry.register(new DefaultImageHeaderParser());
···
registry
.append(ByteBuffer.class, new ByteBufferEncoder())
···
.append(Registry.BUCKET_BITMAP, ByteBuffer.class, Bitmap.class, byteBufferBitmapDecoder)
···
.append(Bitmap.class, Bitmap.class, UnitModelLoader.Factory.<Bitmap>getInstance())
.append(
Registry.BUCKET_BITMAP, Bitmap.class, Bitmap.class, new UnitBitmapDecoder())
.append(Bitmap.class, bitmapEncoder)
···
.register(new ByteBufferRewinder.Factory())
···
.register(
Bitmap.class,
BitmapDrawable.class,
new BitmapDrawableTranscoder(resources))
···
;
ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
glideContext =
new GlideContext(
context,
arrayPool,
registry,
imageViewTargetFactory,
defaultRequestOptions,
defaultTransitionOptions,
engine,
logLevel);
}
这里主要做了三件事:
1.保存在GlideBuilder中完成初始化的对象;
2.初始化Registry对象,该对象中注册了一系列资源转换和编解码的工具类,后续流程会从中查找对应的工具类去解析和处理资源;
3.初始化GlideContext对象,该对象继承自ContextWrapper,后续的流程中会通过它获取注册表和引擎等加载资源所需的对象。
以上完成了Glide对象的创建和初始化。回到Glide的getRetriever方法中,这里将返回RequestManagerRetriever对象,接下来是通过它获取RequestManager对象。
RequestManager获取
RequestManagerRetriever类的get方法也有多个重载:
with方法需要多个重载主要是因为这里,这里根据参数类型查找FragmentManager,利用它实现和当前activity的生命周期绑定。
先看get(Context):
@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)) {
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的类型再调用相应的get方法。若当前非主线程或上下文是Application,直接调用getApplicationManager方法(这种情况下不会绑定生命周期)。
不进行生命周期绑定的RequestManager
当在子线程调用with方法,或传入上下文为application时,会通过getApplicationManager方法返回RequestManager对象:
@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.
// TODO(b/27524013): Factor out this Glide.get() call.
Glide glide = Glide.get(context.getApplicationContext());
applicationManager =
factory.build(
glide,
// ApplicationLifecycle实现Lifecycle接口,用于跟踪和通知Application的生命周期事件。
new ApplicationLifecycle(),
new EmptyRequestManagerTreeNode(),
context.getApplicationContext());
}
}
}
return applicationManager;
}
该方法会返回一个单例的RequestManager对象,通过工厂模式创建,factory在RequestManagerRetriever实例化时候赋值,默认为DEFAULT_FACTORY:
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);
}
};
可以看到build方法直接new了一个RequestManager对象,接着看看RequestManager的构造方法:
public RequestManager(
@NonNull Glide glide, @NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode treeNode, @NonNull Context context) {
this(
glide,
lifecycle,
treeNode,
new RequestTracker(),
glide.getConnectivityMonitorFactory(),
context);
}
// Our usage is safe here.
@SuppressWarnings("PMD.ConstructorCallsOverridableMethod")
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
this.glide = glide;
this.lifecycle = lifecycle;
this.treeNode = treeNode;
// requestTracker用于跟踪、取消和重新启动进行中、已完成和失败的请求。
this.requestTracker = requestTracker;
this.context = context;
// 创建网络连接监听器,当网络恢复可用时会通过requestTracker尝试重启请求。
connectivityMonitor =
factory.build(
context.getApplicationContext(),
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.
// 在主线程添加LifecycleListener到Lifecycle中
if (Util.isOnBackgroundThread()) {
mainHandler.post(addSelfToLifecycle);
} else {
lifecycle.addListener(this);
}
lifecycle.addListener(connectivityMonitor);
setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
// 将自身保存到glide的managers成员变量中(managers为一个ArrayList)。
glide.registerRequestManager(this);
}
这里的lifecycle为ApplicationLifecycle,它的addListener方法只是通知新的监听器已启动。
与当前Activity进行生命周期绑定的RequestManager
get的其他重载方法都是试图获取到FragmentManager,然后调用supportFragmentGet方法或者fragmentGet方法查找或创建RequestManager对象。
(ps:fragmentGet方法适配android.app.FragmentManager,已弃用)
这里以get(FragmentActivity)为例:
@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
// 获取FragmentManager
FragmentManager fm = activity.getSupportFragmentManager();
return supportFragmentGet(
activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
关键在supportFragmentGet方法:
@NonNull
private RequestManager supportFragmentGet(
@NonNull Context context,
@NonNull FragmentManager fm,
@Nullable Fragment parentHint,
boolean isParentVisible) {
// 查找SupportRequestManagerFragment对象,它就是一个Fragment
SupportRequestManagerFragment current =
getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
// 从SupportRequestManagerFragment中获取requestManager
RequestManager requestManager = current.getRequestManager();
// 若不存在则创建,之后保存在SupportRequestManagerFragment中
if (requestManager == null) {
// TODO(b/27524013): Factor out this Glide.get() call.
Glide glide = Glide.get(context);
// 这里创建RequestManager时传入了ActivityFragmentLifecycle
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
该方法中会通过getSupportRequestManagerFragment方法获取一个Fragment,返回其中的RequestManager,若不存在则新建一个,并保存在Fragment中。
接着看getSupportRequestManagerFragment方法:
@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
@NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
// 通过tag查找当前页面中的指定Fragment
SupportRequestManagerFragment current =
(SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
// 获取已创建但等待往当前页面添加的Fragment,避免fm add fragment期间重复创建
current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
// 初始化SupportRequestManagerFragment
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
if (isParentVisible) {
current.getGlideLifecycle().onStart();
}
// 保存到集合中避免重复创建
pendingSupportRequestManagerFragments.put(fm, current);
// 将SupportRequestManagerFragment添加到当前页面中
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
// 在handler的handleMessage中会将上面保存的从集合中移除
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
这里可以看出,Glide是通过往当前页面添加一个Fragment,借助Fragment的生命周期来通知RequestManager,来实现绑定管理。
SupportRequestManagerFragment和RequestManager之间是通过ActivityFragmentLifecycle来实现生命周期回调:
public SupportRequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
@VisibleForTesting
@SuppressLint("ValidFragment")
public SupportRequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
this.lifecycle = lifecycle;
}
在supportFragmentGet方法中创建RequestManager时,会传入SupportRequestManagerFragment的lifecycle成员变量:
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
而在RequestManager的构造方法中,又会向这个lifecycle中注册LifecycleListener接口的实现类即RequestManager自身:
if (Util.isOnBackgroundThread()) {
// 发送到主线程添加
mainHandler.post(addSelfToLifecycle);
} else {
// 添加自身,RequestManager实现了LifecycleListener接口
lifecycle.addListener(this);
}
// 添加网络监听器
lifecycle.addListener(connectivityMonitor);
因此实现了绑定关系:
@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();
}
在Fragment的生命周期回调方法中调用lifecycle的对应方法,而lifecycle中又会调用LifecycleListener接口的相应方法,即RequestManager的onStart、onStop、onDestroy方法。
总结
Glide的with方法会初始化Glide单例对象,并完成一系列默认和自定义配置。之后通过它的requestManagerRetriever成员变量查找创建返回RequestManager对象,后续会通过这个RequestManager进行资源请求的管理。在获取RequestManager的过程中,会通过往当前页面添加一个Fragment,来实现RequestManager和页面生命周期绑定。