本文基于Glide4.9.0版本讲解。
Glide目前是Android开发中主流的图片加载框架。有必要花时间研究一下它的实现原理。因此,从本文开始将对Glide主要流程进行分析,由于Glide的加载链条比较长,便于理解我们分开分析,先分析Glide.with过程。
/**
* 根据FragmentActivity获取Glide对象,并将加载过程跟FragmentActivity生命周期绑定。
*
* @param activity The activity to use.
* @return A RequestManager for the given FragmentActivity that can be used to start a load.
*/
@NonNull
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
调用了getRetriever方法。
@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context 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();
}
/** Internal method. */
@NonNull
public RequestManagerRetriever getRequestManagerRetriever() {
return requestManagerRetriever;
}
根据getRequestManagerRetriever方法我们发现RequestManagerRetriever对象是在Glide类的属性,我们看一下get方法中是如何初始化的。
/**
* 单例
*
* @return the singleton
*/
@NonNull
public static Glide get(@NonNull Context context) {
if (glide == null) {
//获取注解生成的AppGlideModule
GeneratedAppGlideModule annotationGeneratedModule =
getAnnotationGeneratedGlideModules(context.getApplicationContext());
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context, annotationGeneratedModule);
}
}
}
return glide;
}
GeneratedAppGlideModule方法通过反射实例化AppGlideModule对象并返回。
@Nullable
@SuppressWarnings({"unchecked", "TryWithIdenticalCatches", "PMD.UnusedFormalParameter"})
private static GeneratedAppGlideModule getAnnotationGeneratedGlideModules(Context context) {
GeneratedAppGlideModule result = null;
try {
Class clazz =
(Class)
Class.forName("com.bumptech.glide.GeneratedAppGlideModuleImpl");
result =
clazz.getDeclaredConstructor(Context.class).newInstance(context.getApplicationContext());
} catch (ClassNotFoundException e) {
if (Log.isLoggable(TAG, Log.WARN)) {
Log.w(
TAG,
"Failed to find GeneratedAppGlideModule. You should include an"
+ " annotationProcessor compile dependency on com.github.bumptech.glide:compiler"
+ " in your application and a @GlideModule annotated AppGlideModule implementation"
+ " or LibraryGlideModules will be silently ignored");
}
// These exceptions can't be squashed across all versions of Android.
} catch (InstantiationException e) {
throwIncorrectGlideModule(e);
} catch (IllegalAccessException e) {
throwIncorrectGlideModule(e);
} catch (NoSuchMethodException e) {
throwIncorrectGlideModule(e);
} catch (InvocationTargetException e) {
throwIncorrectGlideModule(e);
}
return result;
}
get方法在返回Glide实例之前,需要在checkAndInitializaGlide方法中进行一些初始化的操作。
@GuardedBy("Glide.class")
private static void checkAndInitializeGlide(
@NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
// In the thread running initGlide(), one or more classes may call Glide.get(context).
// Without this check, those calls could trigger infinite recursion.
//加入状态为控制并发初始化的情况
if (isInitializing) {
throw new IllegalStateException(
"You cannot call Glide.get() in registerComponents(),"
+ " use the provided Glide instance instead");
}
isInitializing = true;
initializeGlide(context, generatedAppGlideModule);
isInitializing = false;
}
@GuardedBy("Glide.class")
private static void initializeGlide(
@NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
}
@GuardedBy("Glide.class")
@SuppressWarnings("deprecation")
private static void initializeGlide(
@NonNull Context context,
@NonNull GlideBuilder builder,
@Nullable GeneratedAppGlideModule annotationGeneratedModule) {
Context applicationContext = context.getApplicationContext();
List manifestModules = Collections.emptyList();
//1.注解生成的Module为空或者支持解析Manifest配置的Module,则创建ManifestParser解析Manifest中配置的Module
if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
manifestModules = new ManifestParser(applicationContext).parse();
}
//2.如果有注解生成的Module且屏蔽的Module集合不为空,则过率Manifest中配置的Module。
if (annotationGeneratedModule != null
&& !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {
Set> excludedModuleClasses = annotationGeneratedModule.getExcludedModuleClasses();
Iterator 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());
}
}
//3.初始化RequestManager的工厂对象,赋值给GlideBuilder
RequestManagerRetriever.RequestManagerFactory factory =
annotationGeneratedModule != null
? annotationGeneratedModule.getRequestManagerFactory()
: null;
builder.setRequestManagerFactory(factory);
//4.依次回调用外部配置的Module中的applyOptions方法,实现GlideBuilder配置的修改。
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
module.applyOptions(applicationContext, builder);
}
if (annotationGeneratedModule != null) {
annotationGeneratedModule.applyOptions(applicationContext, builder);
}
//5.创建Glide对象
Glide glide = builder.build(applicationContext);
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
try {
module.registerComponents(applicationContext, glide, glide.registry);
} catch (AbstractMethodError e) {
throw new IllegalStateException(
"Attempting to register a Glide v3 module. If you see this, you or one of your"
+ " dependencies may be including Glide v3 even though you're using Glide v4."
+ " You'll need to find and remove (or update) the offending dependency."
+ " The v3 module name is: "
+ module.getClass().getName(),
e);
}
}
if (annotationGeneratedModule != null) {
annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
}
//6. 注册Application 生命周期监听。内存紧张时把BitmapPool、MemoryCache和ArrayPool都清空
applicationContext.registerComponentCallbacks(glide);
Glide.glide = glide;
}
public final class GlideBuilder {
//图片转换处理集合
private final Map, TransitionOptions, ?>> defaultTransitionOptions = new ArrayMap<>();
//图片加载引擎,负责启动并管理缓存资源
private Engine engine;
//Lru策略的图片池,内存不足时自动清空
private BitmapPool bitmapPool;
//Lru策略的数组池,用于读写IO,内存不足时自动清空
private ArrayPool arrayPool;
// Lru策略的内存缓存池,内存不足时自动清空
private MemoryCache memoryCache;
//线程池,用于查找内存缓存,最大线程数为4,具体取决于cpu
private GlideExecutor sourceExecutor;
//线程池,用于查找本地磁盘缓存,最大线程数为4,具体取决于cpu
private GlideExecutor diskCacheExecutor;
//用于创建本地磁盘缓存对象的工厂,默认本地磁盘缓存size为250M
private DiskCache.Factory diskCacheFactory;
//内存计算器,它通过获取手机硬件常量和手机的屏幕密度、宽度和长度来计算出最适合当前情况的内存缓存的大小
private MemorySizeCalculator memorySizeCalculator;
//用于生产网络状态监听事件的工厂
private ConnectivityMonitorFactory connectivityMonitorFactory;
private int logLevel = Log.INFO;
//设置Glide的配置选项
private RequestOptionsFactory defaultRequestOptionsFactory =
new RequestOptionsFactory() {
@NonNull
@Override
public RequestOptions build() {
return new RequestOptions();
}
};
//用于创建RequestManager对象的工厂
@Nullable private RequestManagerFactory requestManagerFactory;
//线程池,用于加载gif图片,默认线程数为1~2,最大数取决于cpu的核数
private GlideExecutor animationExecutor;
// 是否将保留图片资源数据不给回收,默认为false 需要注意的是,设为true将会导致更大的内存消耗,增加crash的几率
private boolean isActiveResourceRetentionAllowed;
//全局网络请求集合,每次网络请求都会回调
@Nullable private List> defaultRequestListeners;
//...省略部分代码
@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();
}
if (connectivityMonitorFactory == null) {
connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
}
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());
}
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(),
animationExecutor,
isActiveResourceRetentionAllowed);
}
if (defaultRequestListeners == null) {
defaultRequestListeners = Collections.emptyList();
} else {
defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
}
//实例化RequestManagerRetriever对象,RequestManagerRetriever 是 Handler.CallBack 实现类,同时也是生命周期的一个管理类
RequestManagerRetriever requestManagerRetriever =
new RequestManagerRetriever(requestManagerFactory);
return new Glide(
context,
engine,
memoryCache,
bitmapPool,
arrayPool,
requestManagerRetriever,
connectivityMonitorFactory,
logLevel,
defaultRequestOptionsFactory,
defaultTransitionOptions,
defaultRequestListeners,
isLoggingRequestOriginsEnabled,
isImageDecoderEnabledForBitmaps,
hardwareBitmapFdLimit);
}
}
RequestManagerRetriever.get(FragmentActivity)
RequestManagerRetriever
是 Handler.CallBack
实现类,同时也是生命周期的一个管理类。
@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
//是否在子线程运行
if (Util.isOnBackgroundThread()) {
//暂时忽略子线程启动的流程
return get(activity.getApplicationContext());
} else {
//检查Activity是否被销毁
assertNotDestroyed(activity);
FragmentManager fm = activity.getSupportFragmentManager();
//
return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
RequestManagerRetriever.supportFragmentGet
@NonNull
private RequestManager supportFragmentGet(
@NonNull Context context,
@NonNull FragmentManager fm,
@Nullable Fragment parentHint,
boolean isParentVisible) {
//获取监控FragmentActivity生命周期的Fragment
SupportRequestManagerFragment current =
getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
//获取SupportRequestManagerFragment中的RequestManager对象
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
// TODO(b/27524013): Factor out this Glide.get() call.
Glide glide = Glide.get(context);
//为空,重新创建一个并存到SupportRequestManagerFragment
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
@NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
//查找SupportRequestManagerFragment
SupportRequestManagerFragment current =
(SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
//若为空从缓存中取
current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
//依然为空则重新创建一个
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
//若Activity可见,回调生命周期监听
if (isParentVisible) {
current.getGlideLifecycle().onStart();
}
//缓存起来
pendingSupportRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
//发送消息,清空刚存进去的Fragment,这个地方没太理解为什么这样搞
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
创建了RequestManager,默认情况下使用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);
}
};
到此,Glide
的 with(FragmentActivity)
的流程分析完成了。接下来分析load过程