Glide图片加载三步曲源码解析
Glide图片加载框架大家都应该不会陌生,集成使用起来非常的简单,但是之前都没怎么看过Glide的源码,现在自己照着源码钻研一下,看看到底是如何通过这三个方法,就能加载出图片,做到这么强大的功能的。源码基于Glide4.9.0
Glide的基本使用
Glide最基本的使用方法就是三步,先with(),再load(),最后就是into(),然而就是这么三步简单的代码,就能将图片加载到我们的ImageView中,那么通过调用这三个方法到底是如何实现图片加载的呢?此次就对这个三个方法进行解析。
Glide.with(this).load(url).into(ImageView);
with()方法解析
@NonNull
public static RequestManager with(@NonNull Context context) {
return getRetriever(context).get(context);
}
@NonNull
public static RequestManager with(@NonNull Activity activity) {
return getRetriever(activity).get(activity);
}
@NonNull
public static RequestManager with(@NonNull FragmentActivity activity) {
return getRetriever(activity).get(activity);
}
@NonNull
public static RequestManager with(@NonNull Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
@SuppressWarnings("deprecation")
@Deprecated
@NonNull
public static RequestManager with(@NonNull android.app.Fragment fragment) {
return getRetriever(fragment.getActivity()).get(fragment);
}
@NonNull
public static RequestManager with(@NonNull View view) {
return getRetriever(view.getContext()).get(view);
}
// Glide中的getRetriever(Context)方法
@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
...// 会判断context不能为空,否者抛出异常
// 通过Glide.get(context)获取或创建Glide单例对象
// 通过glide对象获取RequestManagerRetriever对象
return Glide.get(context).getRequestManagerRetriever();
}
由以上源码可以看出with()方法一共做了两件事
- 调用getRetriever()方法,获取到RequestManagerRetriever对象
- 然后通过RequestManagerRetriever对象调用get()方法,获取到一个RequestManager请求管理器对象
创建或获取Glide单例对象
// Glide中的get(Context)方法,获取线程安全的Glide单例对象
@NonNull
public static Glide get(@NonNull Context context) {
if (glide == null) {
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context);
}
}
}
return glide;
}
// 检查Glide是否正在初始化,未在初始化则进行初始化
private static void checkAndInitializeGlide(@NonNull Context context) {
// 检查Glide是否正在初始化,保证Glide只被初始化一次
if (isInitializing) {
throw new IllegalStateException("You cannot call Glide.get() in registerComponents(),"
+ " use the provided Glide instance instead");
}
isInitializing = true;
initializeGlide(context);
isInitializing = false;
}
// 初始化Glide
private static void initializeGlide(@NonNull Context context) {
// 创建了一个GlideBuilder()实例传入initializeGlide()方法
initializeGlide(context, new GlideBuilder());
}
// 初始化Glide
@SuppressWarnings("deprecation")
private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
Context applicationContext = context.getApplicationContext();
// 获取@GlideModule注解驱动生成的GeneratedAppGlideModuleImpl和GeneratedAppGlideModuleFactory类
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;
}
// ... 日志输出
iterator.remove();
}
}
// ... 日志输出
// 尝试从注解生成的annotationGeneratedModule中获取RequestManager的构造工厂对象
RequestManagerRetriever.RequestManagerFactory factory =
annotationGeneratedModule != null
? annotationGeneratedModule.getRequestManagerFactory() : null;
// 向GlideBuilder中设置管理器工厂
builder.setRequestManagerFactory(factory);
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
module.applyOptions(applicationContext, builder);
}
if (annotationGeneratedModule != null) {
annotationGeneratedModule.applyOptions(applicationContext, builder);
}
// 通过GlideBuilder中的build()方法创建Glide对象
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);
}
applicationContext.registerComponentCallbacks(glide);
// 给Glide对象赋值
Glide.glide = glide;
}
可以看到通过GlideBuilder类中的build()方法创建Glide对象,并且保存在Glide类中的静态成员变量glide中
Glide对象的创建过程
@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();
}
// 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());
}
// 资源缓存
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);
}
if (defaultRequestListeners == null) {
defaultRequestListeners = Collections.emptyList();
} else {
defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
}
// 创建了一个RequestManagerRetriever对象
RequestManagerRetriever requestManagerRetriever =
new RequestManagerRetriever(requestManagerFactory);
// 创建Glide对象
return new Glide(
context,
engine,
memoryCache,
bitmapPool,
arrayPool,
requestManagerRetriever,
connectivityMonitorFactory,
logLevel,
defaultRequestOptions.lock(),
defaultTransitionOptions,
defaultRequestListeners,
isLoggingRequestOriginsEnabled);
}
// 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,
@NonNull List<RequestListener<Object>> defaultRequestListeners,
boolean isLoggingRequestOriginsEnabled) {
// 将GlideBuild中的管理引擎,线程池,缓存池等保存
this.engine = engine;
this.bitmapPool = bitmapPool;
this.arrayPool = arrayPool;
this.memoryCache = memoryCache;
this.requestManagerRetriever = requestManagerRetriever;
this.connectivityMonitorFactory = connectivityMonitorFactory;
...
registry = new Registry();
// 创建一个Registry,管理组件注册,以扩展或替换Glide的默认加载、解码和编码逻辑。
...
// 创建一个GlideContext上下文
glideContext =
new GlideContext(
context,
arrayPool,
registry,
imageViewTargetFactory,
defaultRequestOptions,
defaultTransitionOptions,
defaultRequestListeners,
engine,
isLoggingRequestOriginsEnabled,
logLevel);
}
Glide的创建过程非常的复杂,构建了一系列的线程池,内存缓存策略,对象复用池,工厂类等,这里就不再进行深入探索。
在创建GlideBuilder.build的时候, 创建了一个RequestManagerRetriever对象并且传递到了Glide构造方法,并且进行保存,
于是通过Glide.getRequestManagerRetriever() 就可以获取到RequestManagerRetriever这个对象了
获取RequestManage对象
// 首先通过Glide对象获取RequestManagerRetriever对象
@NonNull
public RequestManagerRetriever getRequestManagerRetriever() {
return requestManagerRetriever;
}
// 然后通过RequestManagerRetriever对象获取RequestManager对象(RequestManagerRetriever类中的方法)
@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)) {
// 判断当前线程是在主线程中并且传入的context不是ApplicationContext
// 根据传入的context调用不同的get()方法
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());
}
}
// 如果是ApplicationContext直接调用getApplicationManager()方法获取RequestManager对象
return getApplicationManager(context);
}
// 传入ApplicationContext获取RequestManager对象(RequestManagerRetriever类中的方法)
@NonNull
private RequestManager getApplicationManager(@NonNull Context context) {
// 传入ApplicationContext或者在子线程时,会调用该方法创建或获取RequestManager对象
if (applicationManager == null) {
synchronized (this) {
if (applicationManager == null) {
Glide glide = Glide.get(context.getApplicationContext());
// 通过RequestManagerFactory接口中的build方法,创建RequestManager对象...todo(没看到在哪里实现的)
applicationManager =
factory.build(
glide,
new ApplicationLifecycle(),
new EmptyRequestManagerTreeNode(),
context.getApplicationContext());
}
}
}
return applicationManager;
}
// 传入的context为FragmentActivity
@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
// 判断如果是子线程,则使用get(ApplicationContext)获取RequestManager对象
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
// 判断当前activity是否已经销毁,销毁会抛出异常
assertNotDestroyed(activity);
FragmentManager fm = activity.getSupportFragmentManager();
// 通过supportFragmentGet方法获取RequestManager对象
return supportFragmentGet(
activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
// 传入的context为Fragment
@NonNull
public RequestManager get(@NonNull 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, fragment.isVisible());
}
}
// 传入的context为Activity
@SuppressWarnings("deprecation")
@NonNull
public RequestManager get(@NonNull Activity activity) {
if (Util.isOnBackgroundThread()) {
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
android.app.FragmentManager fm = activity.getFragmentManager();
return fragmentGet(
activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
// 传入的context为View
@SuppressWarnings("deprecation")
@NonNull
public RequestManager get(@NonNull 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());
// The view might be somewhere else, like a service.
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);
}
// Standard Fragments.
android.app.Fragment fragment = findFragment(view, activity);
if (fragment == null) {
return get(activity);
}
return get(fragment);
}
// 判断当前activity是否已经销毁
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
private static void assertNotDestroyed(@NonNull Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && activity.isDestroyed()) {
throw new IllegalArgumentException("You cannot start a load for a destroyed activity");
}
}
// 通过supportFragmentGet方法获取RequestManager对象
@NonNull
private RequestManager supportFragmentGet(
@NonNull Context context,
@NonNull FragmentManager fm,
@Nullable Fragment parentHint,
boolean isParentVisible) {
// 通过getSupportRequestManagerFragment方法创建一个隐藏的Fragment
SupportRequestManagerFragment current =
getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
// 通过该fragment获取到RequestManager对象
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
// 如果requestManager对象为空,则通过RequestManagerFactory构建一个
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
// 将requestManager保存到当前fragment中
current.setRequestManager(requestManager);
}
return requestManager;
}
@SuppressWarnings({"deprecation", "DeprecatedIsStillUsed"})
@Deprecated
@NonNull
private RequestManager fragmentGet(@NonNull Context context,
@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
// 从 Activity 中获取一个RequestManagerFragment, 用于监管Activity的声明周期
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
// 获取Fragment中保存的当前页面的请求管理器
RequestManager requestManager = current.getRequestManager();
// 不存在则创建一个请求管理器保存在RequestManagerFragment中
if (requestManager == null) {
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
// 创建一个隐藏的Fragment
@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
@NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
// 从FragmentManager中获取这个Fragment
SupportRequestManagerFragment current =
(SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
// 不存在则添加一个
if (current == null) {
// 从pendingSupportRequestManagerFragments中获取一个
current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
// 没有获取到则创建一个
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
if (isParentVisible) {
current.getGlideLifecycle().onStart();
}
// 添加到等待被添加的缓存中
pendingRequestManagerFragments.put(fm, current);
// 因为添加到FragmentManager有延迟
// 防止同一时间创建了两个RequestManagerFragment对象添加到Activity中
pendingSupportRequestManagerFragments.put(fm, current);
// 添加到FragmentManager中
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
// 加到FragmentManager成功, 通过Handler移除这个缓存
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
从源码中可以看到,RequestManagerRetriever.get()方法会判断Context的类型,根据传入不同的的类型,获取到不同RequestManager对象
- 若在主线程并且不为
Application类型的Context则找寻其依赖的Activity - 若非主线程或为Application类型的
Context,则使用ApplicationManager
传入Application类型的Context处理是比较简单的,因为Application对象的生命周期即应用程序的生命周期,因此Glide并不需要做什么特殊的处理,它自动就是和应用程序的生命周期是同步的,如果应用程序关闭的话,Glide的加载也会同时终止。
而非Appliction的Context则主要是在Activity页面中添加一个RequestManagerFragment实例, 以便用于监听Activity的生命周期, 然后给这个Fragment注入一个RequestManager。因为Glide并没有办法知道Activity的生命周期,所以采用这种添加隐藏Fragment的技巧,因为Fragment的生命周期和Activity是同步的,如果Activity被销毁了,Fragment是可以监听到的,当Activity被销毁后,Glide就能捕获到并且停止加载图片了。
load()方法解析
RequestManager类中load()方法同样很很多个重载方法,这里只列出常用的几个,会根据传入的参数类型调用RequestBuilder类中的不同的load()重载方法
//RequestManager类中的方法
@NonNull
@CheckResult
@Override
public RequestBuilder<Drawable> load(@Nullable Bitmap bitmap) {
// 通过调用asDrawable()方法,创建出一个RequestBuilder对象
return asDrawable().load(bitmap);
}
@NonNull
@CheckResult
@Override
public RequestBuilder<Drawable> load(@Nullable Drawable drawable) {
return asDrawable().load(drawable);
}
@NonNull
@CheckResult
@Override
public RequestBuilder<Drawable> load(@Nullable String string) {
return asDrawable().load(string);
}
@NonNull
@CheckResult
@Override
public RequestBuilder<Drawable> load(@Nullable File file) {
return asDrawable().load(file);
}
@NonNull
@CheckResult
public RequestBuilder<Drawable> asDrawable() {
// 全部都以Drawable类型传入as方法
return as(Drawable.class);
}
@NonNull
@CheckResult
public <ResourceType> RequestBuilder<ResourceType> as(
@NonNull Class<ResourceType> resourceClass) {
// 创建出RequestBuilder对象
return new RequestBuilder<>(glide, this, resourceClass, context);
}
其实load方法中,如果不去深究创建RequestBuilder对象的话,是非常简单的,所有重载方法都会先调用asDrawable()方法,传入Drawable类型,创建出RequestBuilder对象,然后再调用RequestBuilder中的load()方法
RequestBuilder
// RequestBuilder的构造方法
protected RequestBuilder(
@NonNull Glide glide,
RequestManager requestManager,
Class<TranscodeType> transcodeClass,
Context context) {
this.glide = glide;
this.requestManager = requestManager;
this.transcodeClass = transcodeClass;
this.context = context;
this.transitionOptions = requestManager.getDefaultTransitionOptions(transcodeClass);
this.glideContext = glide.getGlideContext();
// 初始化requestManager中默认的请求监听
initRequestListeners(requestManager.getDefaultRequestListeners());
// 根据requestManager中的默认请求选项进行赋值,也就是我们经常用的占位图,错误图,缓存策略等选项
apply(requestManager.getDefaultRequestOptions());
}
@NonNull
@CheckResult
@Override
public RequestBuilder<TranscodeType> load(@Nullable Bitmap bitmap) {
// 传入Bitmap时会设置不使用磁盘缓存
return loadGeneric(bitmap)
.apply(diskCacheStrategyOf(DiskCacheStrategy.NONE));
}
@NonNull
@CheckResult
@Override
public RequestBuilder<TranscodeType> load(@Nullable Drawable drawable) {
// 传入Drawable时也会设置不使用磁盘缓存
return loadGeneric(drawable)
.apply(diskCacheStrategyOf(DiskCacheStrategy.NONE));
}
@NonNull
@Override
@CheckResult
public RequestBuilder<TranscodeType> load(@Nullable String string) {
return loadGeneric(string);
}
@NonNull
@CheckResult
@Override
public RequestBuilder<TranscodeType> load(@Nullable File file) {
return loadGeneric(file);
}
// 最终都会调用该方法
@NonNull
private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
this.model = model;
// 标识是否已经调用了load()方法,在调用into()方法是会做判断,没有设置为true会抛出异常
// 也就是在调用into()方法前,必须调用load()方法
isModelSet = true;
return this;
}
into()方法
@NonNull
public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view) {
// 判断是否在主线程中执行
Util.assertMainThread();
// 判空操作,view不能为空
Preconditions.checkNotNull(view);
// 根据view的scaleType重构RequestOptions
BaseRequestOptions<?> requestOptions = this;
if (!requestOptions.isTransformationSet()
&& requestOptions.isTransformationAllowed()
&& view.getScaleType() != null) {
switch (view.getScaleType()) {
case CENTER_CROP:
requestOptions = requestOptions.clone().optionalCenterCrop();
break;
case CENTER_INSIDE:
requestOptions = requestOptions.clone().optionalCenterInside();
break;
case FIT_CENTER:
case FIT_START:
case FIT_END:
requestOptions = requestOptions.clone().optionalFitCenter();
break;
case FIT_XY:
requestOptions = requestOptions.clone().optionalCenterInside();
break;
case CENTER:
case MATRIX:
default:
// Do nothing.
}
}
// 调用into方法,创建执行请求
return into(
glideContext.buildImageViewTarget(view, transcodeClass),
/*targetListener=*/ null,
requestOptions,
Executors.mainThreadExecutor());
}
private <Y extends Target<TranscodeType>> Y into(
@NonNull Y target,
@Nullable RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> options,
Executor callbackExecutor) {
Preconditions.checkNotNull(target);
// 调用into()方法之前 必须要先调用load()方法,isModelSet会在调用load方法之后赋值为true
if (!isModelSet) {
throw new IllegalArgumentException("You must call #load() before calling #into()");
}
// 调用buildRequest()方法,构建一个Request请求
Request request = buildRequest(target, targetListener, options, callbackExecutor);
Request previous = target.getRequest();
if (request.isEquivalentTo(previous)
&& !isSkipMemoryCacheWithCompletePreviousRequest(options, previous)) {
request.recycle();
if (!Preconditions.checkNotNull(previous).isRunning()) {
previous.begin();
}
return target;
}
// 清除target之前的请求,释放资源
requestManager.clear(target);
//给ViewTarget设置这个Request请求,即Glide加载图片的请求
target.setRequest(request);
// 调用RequestManager.track()方法执行请求
requestManager.track(target, request);
return target;
}
可以看到into()方法的代码其实并不多,但是里面的涉及到的调用却嵌套了很多层,现在就一步一步的解析它里面调用的方法。
配置options
加载图片的时候会根据view的scaleType重构RequestOptions,所以先对这个进行解析,这里会根据不同的scaleType方式,调用不同的方法,
不过基本上差不多,这里选取其中的一种的requestOptions.clone().optionalFitCenter()进行解析
public abstract class BaseRequestOptions<T extends BaseRequestOptions<T>> implements Cloneable {
@NonNull
private Options options = new Options();
@NonNull
private Map<Class<?>, Transformation<?>> transformations = new CachedHashCodeArrayMap<>();
}
// clone方法,主要是对一些资源参数进行初始化赋值
public T clone() {
try {
BaseRequestOptions<?> result = (BaseRequestOptions<?>) super.clone();
result.options = new Options();
result.options.putAll(options);
result.transformations = new CachedHashCodeArrayMap<>();
result.transformations.putAll(transformations);
result.isLocked = false;
// 赋值不进行自动拷贝
result.isAutoCloneEnabled = false;
return (T) result;
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
public T optionalFitCenter() {
// DownsampleStrategy描述降采样压缩的策略
// FitCenter 描述图像变化方式
return optionalScaleOnlyTransform(DownsampleStrategy.FIT_CENTER, new FitCenter());
}
private T optionalScaleOnlyTransform(
@NonNull DownsampleStrategy strategy, @NonNull Transformation<Bitmap> transformation) {
return scaleOnlyTransform(strategy, transformation, false /*isTransformationRequired*/);
}
private T scaleOnlyTransform(
@NonNull DownsampleStrategy strategy,
@NonNull Transformation<Bitmap> transformation,
boolean isTransformationRequired) {
// 这里根据传入的isTransformationRequired值,调用optionalTransform()方法
BaseRequestOptions<T> result = isTransformationRequired
? transform(strategy, transformation) : optionalTransform(strategy, transformation);
result.isScaleOnlyOrNoTransform = true;
return (T) result;
}
final T optionalTransform(@NonNull DownsampleStrategy downsampleStrategy,
@NonNull Transformation<Bitmap> transformation) {
// 调用clone()方法时,赋值的false
if (isAutoCloneEnabled) {
return clone().optionalTransform(downsampleStrategy, transformation);
}
// 调用改方法,主要是保存options配置信息
downsample(downsampleStrategy);
return transform(transformation, /*isRequired=*/ false);
}
public T downsample(@NonNull DownsampleStrategy strategy) {
return set(DownsampleStrategy.OPTION, Preconditions.checkNotNull(strategy));
}
public <Y> T set(@NonNull Option<Y> option, @NonNull Y value) {
if (isAutoCloneEnabled) {
return clone().set(option, value);
}
Preconditions.checkNotNull(option);
Preconditions.checkNotNull(value);
// 保存配置信息
options.set(option, value);
return selfOrThrowIfLocked();
}
T transform(
@NonNull Transformation<Bitmap> transformation, boolean isRequired) {
if (isAutoCloneEnabled) {
return clone().transform(transformation, isRequired);
}
DrawableTransformation drawableTransformation =
new DrawableTransformation(transformation, isRequired);
// 调用了transform的重载方法, 将这个图像变化的方式作用到多种资源类型上
transform(Bitmap.class, transformation, isRequired);
transform(Drawable.class, drawableTransformation, isRequired);
transform(BitmapDrawable.class, drawableTransformation.asBitmapDrawable(), isRequired);
transform(GifDrawable.class, new GifDrawableTransformation(transformation), isRequired);
return selfOrThrowIfLocked();
}
<Y> T transform(
@NonNull Class<Y> resourceClass,
@NonNull Transformation<Y> transformation,
boolean isRequired) {
if (isAutoCloneEnabled) {
return clone().transform(resourceClass, transformation, isRequired);
}
Preconditions.checkNotNull(resourceClass);
Preconditions.checkNotNull(transformation);
// 添加到transformations缓存中
transformations.put(resourceClass, transformation);
fields |= TRANSFORMATION;
isTransformationAllowed = true;
fields |= TRANSFORMATION_ALLOWED;
isScaleOnlyOrNoTransform = false;
if (isRequired) {
fields |= TRANSFORMATION_REQUIRED;
isTransformationRequired = true;
}
return selfOrThrowIfLocked();
}
可以看到options配置操作,无非就是添加添加了图像变化操作, 并且设定采样方式, 分别保存在transformations和options中
构建Target对象
可以看到最后调用into()方法时,调用了glideContext.buildImageViewTarget(view, transcodeClass)来构建Target对象
public class GlideContext extends ContextWrapper {
public <X> ViewTarget<ImageView, X> buildImageViewTarget(
@NonNull ImageView imageView, @NonNull Class<X> transcodeClass) {
return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
}
}
public class ImageViewTargetFactory {
@NonNull
@SuppressWarnings("unchecked")
public <Z> ViewTarget<ImageView, Z> buildTarget(@NonNull ImageView view,
@NonNull Class<Z> clazz) {
// 根据目标编码的类型来创建不同的ViewTarget对象, 因为我们没有asBitmap, 因此这里为Drawable
if (Bitmap.class.equals(clazz)) {
return (ViewTarget<ImageView, Z>) new BitmapImageViewTarget(view);
} else if (Drawable.class.isAssignableFrom(clazz)) {
return (ViewTarget<ImageView, Z>) new DrawableImageViewTarget(view);
} else {
throw new IllegalArgumentException(
"Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
}
}
}
buildRequest创建Request
可以看到into()方法中,调用了buildRequest()方法来创建一个Request,
Request request = buildRequest(target, targetListener, options, callbackExecutor);这里不具体去看到底是如何创建的,最终就是调用SingleRequest.obtain构建一个Request的实例对象
public class RequestBuilder<TranscodeType> extends BaseRequestOptions<RequestBuilder<TranscodeType>>
implements Cloneable,
ModelTypes<RequestBuilder<TranscodeType>> {
private Request buildRequest(
Target<TranscodeType> target,
@Nullable RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> requestOptions,
Executor callbackExecutor) {
return buildRequestRecursive(...);
}
// buildRequestRecursive方法中通过调用buildThumbnailRequestRecursive方法返回Request
private Request buildRequestRecursive(
Target<TranscodeType> target,
@Nullable RequestListener<TranscodeType> targetListener,
@Nullable RequestCoordinator parentCoordinator,
TransitionOptions<?, ? super TranscodeType> transitionOptions,
Priority priority,
int overrideWidth,
int overrideHeight,
BaseRequestOptions<?> requestOptions,
Executor callbackExecutor) {
...
ErrorRequestCoordinator errorRequestCoordinator = null;
if (errorBuilder != null) {
errorRequestCoordinator = new ErrorRequestCoordinator(parentCoordinator);
parentCoordinator = errorRequestCoordinator;
}
Request mainRequest =
buildThumbnailRequestRecursive(...);
if (errorRequestCoordinator == null) {
return mainRequest;
}
// 而该方法中通过obtainRequest创建Request
private Request buildThumbnailRequestRecursive(
Target<TranscodeType> target,
RequestListener<TranscodeType> targetListener,
@Nullable RequestCoordinator parentCoordinator,
TransitionOptions<?, ? super TranscodeType> transitionOptions,
Priority priority,
int overrideWidth,
int overrideHeight,
BaseRequestOptions<?> requestOptions,
Executor callbackExecutor) {
...
// Base case: no thumbnail.
return obtainRequest(...);
}
// 最终通过SingleRequest.obtain返回一个Request
private Request obtainRequest(
Target<TranscodeType> target,
RequestListener<TranscodeType> targetListener,
BaseRequestOptions<?> requestOptions,
RequestCoordinator requestCoordinator,
TransitionOptions<?, ? super TranscodeType> transitionOptions,
Priority priority,
int overrideWidth,
int overrideHeight,
Executor callbackExecutor) {
return SingleRequest.obtain(...);
}
}
Request的分发
可以看到最后调用了requestManager.track(target, request);去分发请求,接下来我们就看看到底这个请求是如何进行分发的
public class RequestManager implements LifecycleListener,
ModelTypes<RequestBuilder<Drawable>> {
synchronized void track(@NonNull Target<?> target, @NonNull Request request) {
// 将加载图片的Target保存到Set集合targets中
targetTracker.track(target);
// 执行请求
requestTracker.runRequest(request);
}
}
public final class TargetTracker implements LifecycleListener {
private final Set<Target<?>> targets =
Collections.newSetFromMap(new WeakHashMap<Target<?>, Boolean>());
public void track(@NonNull Target<?> target) {
targets.add(target);
}
}
public class RequestTracker {
public void runRequest(@NonNull Request request) {
requests.add(request);
if (!isPaused) {
// 开始执行任务
request.begin();
} else {
request.clear();
pendingRequests.add(request);
}
}
}
public final class SingleRequest<R> implements Request,
SizeReadyCallback,
ResourceCallback,
FactoryPools.Poolable {
@Override
public synchronized void begin() {
...
// 正在运行
if (status == Status.RUNNING) {
throw new IllegalArgumentException("Cannot restart a running request");
}
// 资源已经加载完成
if (status == Status.COMPLETE) {
onResourceReady(resource, DataSource.MEMORY_CACHE);
return;
}
status = Status.WAITING_FOR_SIZE;
if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
// 表示尺寸已经准备好了
onSizeReady(overrideWidth, overrideHeight);
} else {
target.getSize(this);
}
if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
&& canNotifyStatusChanged()) {
target.onLoadStarted(getPlaceholderDrawable());
}
}
@Override
public synchronized void onSizeReady(int width, int height) {
stateVerifier.throwIfRecycled();
if (status != Status.WAITING_FOR_SIZE) {
return;
}
// 标识正在运行的状态
status = Status.RUNNING;
float sizeMultiplier = requestOptions.getSizeMultiplier();
this.width = maybeApplySizeMultiplier(width, sizeMultiplier);
this.height = maybeApplySizeMultiplier(height, sizeMultiplier);
// 调用engine.load()方法
loadStatus =
engine.load(
glideContext,
model,
requestOptions.getSignature(),
this.width,
this.height,
requestOptions.getResourceClass(),
transcodeClass,
priority,
requestOptions.getDiskCacheStrategy(),
requestOptions.getTransformations(),
requestOptions.isTransformationRequired(),
requestOptions.isScaleOnlyOrNoTransform(),
requestOptions.getOptions(),
requestOptions.isMemoryCacheable(),
requestOptions.getUseUnlimitedSourceGeneratorsPool(),
requestOptions.getUseAnimationPool(),
requestOptions.getOnlyRetrieveFromCache(),
this,
callbackExecutor);
if (status != Status.RUNNING) {
loadStatus = null;
}
if (IS_VERBOSE_LOGGABLE) {
logV("finished onSizeReady in " + LogTime.getElapsedMillis(startTime));
}
}
}
任务的创建engine.load()
在尺寸准备好后,就会在onSizeReady中调用engine.load()去构建任务
public class Engine implements EngineJobListener,
MemoryCache.ResourceRemovedListener,
EngineResource.ResourceListener {
public synchronized <R> LoadStatus load(
GlideContext glideContext,
Object model,
Key signature,
int width,
int height,
Class<?> resourceClass,
Class<R> transcodeClass,
Priority priority,
DiskCacheStrategy diskCacheStrategy,
Map<Class<?>, Transformation<?>> transformations,
boolean isTransformationRequired,
boolean isScaleOnlyOrNoTransform,
Options options,
boolean isMemoryCacheable,
boolean useUnlimitedSourceExecutorPool,
boolean useAnimationPool,
boolean onlyRetrieveFromCache,
ResourceCallback cb,
Executor callbackExecutor) {
// 根据传入的参数, 构建这个请求的 key
EngineKey key = keyFactory.buildKey(model, signature, width, height, transformations,
resourceClass, transcodeClass, options);
// 从ActiveResources中查找key对应的资源
EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
if (active != null) {
// 若存在, 则直接回调onResourceReady处理后续操作
cb.onResourceReady(active, DataSource.MEMORY_CACHE);
return null;
}
// 从缓存中查找key对应的资源
EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
if (cached != null) {
// 若缓存存在, 则直接回调onResourceReady处理后续操作
cb.onResourceReady(cached, DataSource.MEMORY_CACHE);
return null;
}
// 查找key对应的任务
EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
if (current != null) {
// 如果存在,说明这个任务已经正在执行了, 无需再次构建执行
current.addCallback(cb, callbackExecutor);
// 返回加载的状态
return new LoadStatus(cb, current);
}
// 构建一个新的任务
EngineJob<R> engineJob =
engineJobFactory.build(
key,
isMemoryCacheable,
useUnlimitedSourceExecutorPool,
useAnimationPool,
onlyRetrieveFromCache);
// 构建解码任务
DecodeJob<R> decodeJob =
decodeJobFactory.build(
glideContext,
model,
key,
signature,
width,
height,
resourceClass,
transcodeClass,
priority,
diskCacheStrategy,
transformations,
isTransformationRequired,
isScaleOnlyOrNoTransform,
onlyRetrieveFromCache,
options,
engineJob);
// 保存该任务
jobs.put(key, engineJob);
engineJob.addCallback(cb, callbackExecutor);
// 执行任务
engineJob.start(decodeJob);
return new LoadStatus(cb, engineJob);
}
}
可以看到Engine.load中的事情非常的重要
- 构建这个请求的
key - 从缓存中查找
key对应的资源, 若存在直接回onResourceReady表示资源准备好了- 从
ActiveResources中查找 - 从
Cache缓存中查找
- 从
- 从缓存中查找
key对应的任务- 若存在则说明无需再次获取资源
- 构建新的任务
- 构建引擎任务
EngineJob - 引擎的任务为解码任务
DecodeJob - 将任务添加到缓存, 防止多次构建
- 执行任务
- 构建引擎任务
任务的执行
class EngineJob<R> implements DecodeJob.Callback<R>,
Poolable {
private final GlideExecutor diskCacheExecutor;
private DecodeJob<R> decodeJob;
public synchronized void start(DecodeJob<R> decodeJob) {
this.decodeJob = decodeJob;
// 获取线程池
GlideExecutor executor = decodeJob.willDecodeFromCache()
? diskCacheExecutor : getActiveSourceExecutor();
// 执行任务
executor.execute(decodeJob);
}
}
class DecodeJob<R> implements DataFetcherGenerator.FetcherReadyCallback,
Runnable,
Comparable<DecodeJob<?>>,
Poolable {
@Override
public void run() {
try {
......
// 调用了 runWrapped
runWrapped();
} catch (CallbackException e) {
......
}
}
private void runWrapped() {
switch (runReason) {
case INITIALIZE:
// 1. 获取任务的场景
stage = getNextStage(Stage.INITIALIZE);
// 2. 获取这个场景的执行者
currentGenerator = getNextGenerator();
// 3. 执行者执行任务
runGenerators();
break;
......
}
}
private Stage getNextStage(Stage current) {
switch (current) {
case INITIALIZE:
// 1.1 若我们配置的缓存策略允许从资源缓存中读数据, 则返回Stage.RESOURCE_CACHE
return diskCacheStrategy.decodeCachedResource()
? Stage.RESOURCE_CACHE : getNextStage(Stage.RESOURCE_CACHE);
case RESOURCE_CACHE:
// 1.2 若我们配置的缓存策略允许从源数据缓存中读数据, 则返回 Stage.DATA_CACHE
return diskCacheStrategy.decodeCachedData()
? Stage.DATA_CACHE : getNextStage(Stage.DATA_CACHE);
case DATA_CACHE:
// 1.3 若只能允许从缓存中获取数据, 则直接FINISH, 否则返回Stage.SOURCE, 意为加载一个新的资源
return onlyRetrieveFromCache ? Stage.FINISHED : Stage.SOURCE;
case SOURCE:
case FINISHED:
return Stage.FINISHED;
default:
throw new IllegalArgumentException("Unrecognized stage: " + current);
}
}
private DataFetcherGenerator getNextGenerator() {
switch (stage) {
case RESOURCE_CACHE:
// 资源磁盘缓存的执行者
return new ResourceCacheGenerator(decodeHelper, this);
case DATA_CACHE:
// 源数据磁盘缓存的执行者
return new DataCacheGenerator(decodeHelper, this);
case SOURCE:
// 无缓存, 获取数据的源的执行者
return new SourceGenerator(decodeHelper, this);
case FINISHED:
return null;
default:
throw new IllegalStateException("Unrecognized stage: " + stage);
}
}
private void runGenerators() {
......
boolean isStarted = false;
// 调用 DataFetcherGenerator.startNext() 执行了请求操作
while (!isCancelled && currentGenerator != null
&& !(isStarted = currentGenerator.startNext())) {
stage = getNextStage(stage);
currentGenerator = getNextGenerator();
if (stage == Stage.SOURCE) {
reschedule();
return;
}
}
......
}
}
获取数据源
class SourceGenerator implements DataFetcherGenerator,
DataFetcher.DataCallback<Object>,
DataFetcherGenerator.FetcherReadyCallback {
private final DecodeHelper<?> helper;
public boolean startNext() {
......
loadData = null;
boolean started = false;
while (!started && hasNextModelLoader()) {
// 1. 从 DecodeHelper 的数据加载集合中, 获取一个数据加载器
loadData = helper.getLoadData().get(loadDataListIndex++);
if (loadData != null
&& (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
|| helper.hasLoadPath(loadData.fetcher.getDataClass()))) {
started = true;
// 2. 使用加载器中 fetcher 执行数据加载
loadData.fetcher.loadData(helper.getPriority(), this);
}
}
return started;
}
}
SourceGenerator主要有两步
- 调用
DecodeHelper.getLoadData获取当前请求的数据加载器 - 调用加载器中的
fetcher.loadData真正的执行数据加载
获取数据加载器
final class DecodeHelper<Transcode> {
private final List<LoadData<?>> loadData = new ArrayList<>();
private GlideContext glideContext;
private Object model;
private boolean isLoadDataSet;
List<LoadData<?>> getLoadData() {
if (!isLoadDataSet) {
isLoadDataSet = true;
loadData.clear();
// 1. 从 Glide 注册的 register 中获取请求 model 加载器
List<ModelLoader<Object, ?>> modelLoaders = glideContext.getRegistry().getModelLoaders(model);
// 遍历每一个 modelLoaders
for (int i = 0, size = modelLoaders.size(); i < size; i++) {
// 2. 通过 modelLoaders 构建 loadData
ModelLoader<Object, ?> modelLoader = modelLoaders.get(i);
LoadData<?> current = modelLoader.buildLoadData(model, width, height, options);
if (current != null) {
// 添加到缓存
loadData.add(current);
}
}
}
return loadData;
}
}
它会找到一个ModelLoader的实现类, 通过这个实现类的handles方法, 判断是否可以加载这个model
这里我们的model以网络的URL资源举例, 它的实现类为HttpGlideUrlLoader我们看看它如何构建一个 LoadData对象的
public class HttpGlideUrlLoader implements ModelLoader<GlideUrl, InputStream> {
@Nullable private final ModelCache<GlideUrl, GlideUrl> modelCache;
@Override
public LoadData<InputStream> buildLoadData(@NonNull GlideUrl model, int width, int height,
@NonNull Options options) {
GlideUrl url = model;
.....
int timeout = options.get(TIMEOUT);
// 创建了一个 LoadData 对象, 并且实例化了一个 HttpUrlFetcher 给它
return new LoadData<>(url, new HttpUrlFetcher(url, timeout));
}
}
对于URL的加载, 其fetcher为一个HttpUrlFetcher的实例
执行数据加载
获取到了数据加载器之后, SourceGenerator的startNext中便会调用其fetcher的loadData执行数据的加载了
public class HttpUrlFetcher implements DataFetcher<InputStream> {
public void loadData(@NonNull Priority priority,
@NonNull DataCallback<? super InputStream> callback) {
long startTime = LogTime.getLogTime();
try {
// 获取网络图片, 内部使用了 HttpConnection 实现, 仅仅做了重定向的处理
InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, null, glideUrl.getHeaders());
// 将 inputStream 回调出去
callback.onDataReady(result);
} catch (IOException e) {
......
callback.onLoadFailed(e);
} finally {
......
}
}
}
HttpUrlFetcher它使用了HttpConnection发起了网络请求, 获取了数据流, 至此数据资源的获取就已经完成了, 后面要做的便是最重要的数据处理了, 它通过回调的方式将InputStream扔了出去, 最终会回溯到 DecodeJob的onDataFetcherReady这个方法中
数据源的处理
class DecodeJob<R> implements DataFetcherGenerator.FetcherReadyCallback,
Runnable,
Comparable<DecodeJob<?>>,
Poolable {
private Key currentSourceKey;
private Object currentData;
private DataSource currentDataSource;
private DataFetcher<?> currentFetcher;
@Override
public void onDataFetcherReady(Key sourceKey, Object data, DataFetcher<?> fetcher,
DataSource dataSource, Key attemptedKey) {
this.currentSourceKey = sourceKey; // 保存数据的 key
this.currentData = data; // 保存数据实体
this.currentFetcher = fetcher; // 保存数据的获取器
this.currentDataSource = dataSource;// 数据来源: url 为 REMOTE 类型的枚举, 表示从远程获取
......
if (Thread.currentThread() != currentThread) {
......
} else {
try {
// 调用 decodeFromRetrievedData 解析获取的数据
decodeFromRetrievedData();
} finally {
......
}
}
}
private void decodeFromRetrievedData() {
Resource<R> resource = null;
try {
// 1\. 调用了 decodeFromData 获取资源
resource = decodeFromData(/*HttpUrlFetcher*/currentFetcher, /*InputStream*/currentData,/*REMOTE*/ currentDataSource);
} catch (GlideException e) {
......
}
if (resource != null) {
// 2\. 通知外界资源获取成功了
notifyEncodeAndRelease(resource, currentDataSource);
} else {
......
}
}
}
可以看到对于获取到的数据, 首先要将其解码为Resource类型的资源, 然后再将资源返回给上层
我们先看看它是如何将数据解析成 Resource(非Android系统的Resource) 资源的
资源的获取
class DecodeJob<R> implements DataFetcherGenerator.FetcherReadyCallback,
Runnable,
Comparable<DecodeJob<?>>,
Poolable {
private <Data> Resource<R> decodeFromData(DataFetcher<?> fetcher, Data data,
DataSource dataSource) throws GlideException {
try {
......
// 调用了 decodeFromFetcher
Resource<R> result = decodeFromFetcher(data, dataSource);
......
return result;
} finally {
}
}
private <Data> Resource<R> decodeFromFetcher(Data data, DataSource dataSource)
throws GlideException {
// 1. 获取当前数据类的解析器 LoadPath
LoadPath<Data, ?, R> path = decodeHelper.getLoadPath((Class<Data>) data.getClass());
// 2. 通过解析器来解析来解析数据
return runLoadPath(data, dataSource, path);
}
private <Data, ResourceType> Resource<R> runLoadPath(Data data, DataSource dataSource,
LoadPath<Data, ResourceType, R> path) throws GlideException {
Options options = getOptionsWithHardwareConfig(dataSource);
// 2.1 根据数据类型获取一个数据重造器, 获取的数据为 InputStream, 因此它是一个 InputStreamRewinder 的实例
DataRewinder<Data> rewinder = glideContext.getRegistry().getRewinder(data);
try {
// 2.2 将解析资源的任务转移到了 LoadPath.load 方法中
return path.load( rewinder, options, width, height, new DecodeCallback<ResourceType>(dataSource));
} finally {
rewinder.cleanup();
}
}
}
可以看到为了解析数据, 首先构建了一个LoadPath, 然后创建了一个InputStreamRewinder类型的 DataRewinder, 最终将数据解析的操作到了LoadPath.load方法中
接下来看看这个LoadPath.load 做了哪些处理
public class LoadPath<Data, ResourceType, Transcode> {
public Resource<Transcode> load(DataRewinder<Data> rewinder, @NonNull Options options, int width,
int height, DecodePath.DecodeCallback<ResourceType> decodeCallback) throws GlideException {
......
try {
return loadWithExceptionList(rewinder, options, width, height, decodeCallback, throwables);
} finally {
......
}
}
private final List<? extends DecodePath<Data, ResourceType, Transcode>> decodePaths;
private Resource<Transcode> loadWithExceptionList(DataRewinder<Data> rewinder,
@NonNull Options options, int width, int height, DecodePath.DecodeCallback<ResourceType> decodeCallback,
List<Throwable> exceptions) throws GlideException {
Resource<Transcode> result = null;
// 遍历内部存储的 DecodePath 集合, 通过他们来解析数据
for (int i = 0, size = decodePaths.size(); i < size; i++) {
DecodePath<Data, ResourceType, Transcode> path = decodePaths.get(i);
try {
// 调用 DecodePath.decode 真正进行数据的解析
result = path.decode(rewinder, width, height, options, decodeCallback);
} catch (GlideException e) {
......
}
......
}
return result;
}
}
public class DecodePath<DataType, ResourceType, Transcode> {
public Resource<Transcode> decode(DataRewinder<DataType> rewinder, int width, int height,
@NonNull Options options, DecodeCallback<ResourceType> callback) throws GlideException {
// 1\. 调用 decodeResource 将源数据解析成中间资源
Resource<ResourceType> decoded = decodeResource(rewinder, width, height, options);
// 2\. 调用 DecodeCallback.onResourceDecoded 处理中间资源
Resource<ResourceType> transformed = callback.onResourceDecoded(decoded);
// 3\. 调用 ResourceTranscoder.transcode 将中间资源转为目标资源
return transcoder.transcode(transformed, options);
}
private Resource<ResourceType> decodeResource(DataRewinder<DataType> rewinder, int width,
int height, @NonNull Options options) throws GlideException {
try {
// 1.1 调用了 decodeResourceWithList
return decodeResourceWithList(rewinder, width, height, options, exceptions);
} finally {
......
}
}
@NonNull
private Resource<ResourceType> decodeResourceWithList(DataRewinder<DataType> rewinder, int width,
int height, @NonNull Options options, List<Throwable> exceptions) throws GlideException {
Resource<ResourceType> result = null;
for (int i = 0, size = decoders.size(); i < size; i++) {
ResourceDecoder<DataType, ResourceType> decoder = decoders.get(i);
try {
DataType data = rewinder.rewindAndGet();
if (decoder.handles(data, options)) {
data = rewinder.rewindAndGet();
// 1.2 调用 ResourceDecoder.decode 解析源数据
result = decoder.decode(data, width, height, options);
}
}
......
if (result != null) {
break;
}
}
return result;
}
}
可以看到数据解析的任务最重是通过DecodePath来执行的, 它内部有三个操作
-
调用
decodeResource将源数据解析成资源- 源数据:
InputStream - 中间产物:
Bitmap
- 源数据:
- 调用
DecodeCallback.onResourceDecoded处理资源 -
调用
ResourceTranscoder.transcode将资源转为目标资源- 目标资源类型:
Drawable
- 目标资源类型:
解析源数据
因为本次流程的源数据为InputStream因此它的解析器为StreamBitmapDecoder
public class StreamBitmapDecoder implements ResourceDecoder<InputStream, Bitmap> {
private final Downsampler downsampler;
public Resource<Bitmap> decode(@NonNull InputStream source, int width, int height,
@NonNull Options options)
throws IOException {
......
try {
// 根据请求配置的数据, 对数据流进行采样压缩, 获取到一个 Resource<Bitmap>
return downsampler.decode(invalidatingStream, width, height, options, callbacks);
} finally {
......
}
}
}
可以看到它内部通过Downsampler.decode方法对数据流进行采样压缩, 来获取这个流的Bitmap
- 这个采样的策略就是我们在构建
Request时传入的, 其采样压缩的细节, 并不是我们本次关注的重点
获取到了Resource之后, 又是如何处理这个资源的呢?
资源的处理
当我们将源数据解析成对应的资源之后, 便会调用DecodeCallback.onResourceDecoded处理资源
class DecodeJob<R> implements DataFetcherGenerator.FetcherReadyCallback,
Runnable,
Comparable<DecodeJob<?>>,
Poolable {
private final class DecodeCallback<Z> implements DecodePath.DecodeCallback<Z> {
@Override
public Resource<Z> onResourceDecoded(@NonNull Resource<Z> decoded) {
// 调用了外部类的 onResourceDecoded 方法
return DecodeJob.this.onResourceDecoded(dataSource, decoded);
}
}
private final DeferredEncodeManager<?> deferredEncodeManager = new DeferredEncodeManager<>();
<Z> Resource<Z> onResourceDecoded(DataSource dataSource,
@NonNull Resource<Z> decoded) {
// 1. 获取数据资源的类型
Class<Z> resourceSubClass = (Class<Z>) decoded.get().getClass();
Transformation<Z> appliedTransformation = null;
Resource<Z> transformed = decoded;
// 2. 若非从资源磁盘缓存中获取的数据源, 则对资源进行 transformation 操作
if (dataSource != DataSource.RESOURCE_DISK_CACHE) {
appliedTransformation = decodeHelper.getTransformation(resourceSubClass);
transformed = appliedTransformation.transform(glideContext, decoded, width, height);
}
......
// 3. 构建数据编码的策略
final EncodeStrategy encodeStrategy;
final ResourceEncoder<Z> encoder;
if (decodeHelper.isResourceEncoderAvailable(transformed)) {
encoder = decodeHelper.getResultEncoder(transformed);
encodeStrategy = encoder.getEncodeStrategy(options);
} else {
encoder = null;
encodeStrategy = EncodeStrategy.NONE;
}
// 4 根据编码策略, 构建缓存的 key
Resource<Z> result = transformed;
boolean isFromAlternateCacheKey = !decodeHelper.isSourceKey(currentSourceKey);
if (diskCacheStrategy.isResourceCacheable(isFromAlternateCacheKey, dataSource,
encodeStrategy)) {
......
final Key key;
switch (encodeStrategy) {
case SOURCE:
// 源数据的 key
key = new DataCacheKey(currentSourceKey, signature);
break;
case TRANSFORMED:
// 资源数据的 key
key =
new ResourceCacheKey(......);
break;
default:
throw new IllegalArgumentException("Unknown strategy: " + encodeStrategy);
}
// 5. 初始化编码管理者, 用于提交内存缓存
LockedResource<Z> lockedResult = LockedResource.obtain(transformed);
deferredEncodeManager.init(key, encoder, lockedResult);
result = lockedResult;
}
// 返回 transform 之后的 bitmap
return result;
}
}
可以看到onResourceDecoded中, 主要是对中间资源做了如下的操作
-
对资源进行
transformed操作- 将资源转为目标效果, 如在构建
request时, 设置的CenterCrop
- 将资源转为目标效果, 如在构建
- 构建磁盘缓存的
key
好的, 这个方法执行结束之后, 这个资源就与我们期望的效果一致了, 接下来只需要将它转为目标格式就可以展示了
将数据转为目标格式
目标数据为Drawable, 因此它的转换器为BitmapDrawableTranscoder
public class BitmapDrawableTranscoder implements ResourceTranscoder<Bitmap, BitmapDrawable> {
private final Resources resources;
@Nullable
@Override
public Resource<BitmapDrawable> transcode(@NonNull Resource<Bitmap> toTranscode,
@NonNull Options options) {
// 调用了 LazyBitmapDrawableResource.obtain 获取 Resource<BitmapDrawable> 的实例对象
return LazyBitmapDrawableResource.obtain(resources, toTranscode);
}
}
public final class LazyBitmapDrawableResource implements Resource<BitmapDrawable>,
Initializable {
public static Resource<BitmapDrawable> obtain(
@NonNull Resources resources, @Nullable Resource<Bitmap> bitmapResource) {
......
// 创建了一个 LazyBitmapDrawableResource
return new LazyBitmapDrawableResource(resources, bitmapResource);
}
private LazyBitmapDrawableResource(@NonNull Resources resources,
@NonNull Resource<Bitmap> bitmapResource) {
this.resources = Preconditions.checkNotNull(resources);
this.bitmapResource = Preconditions.checkNotNull(bitmapResource);
}
public BitmapDrawable get() {
// Get 方法反回了一个 BitmapDrawable 对象
return new BitmapDrawable(resources, bitmapResource.get());
}
}
转化成目标数据也比较的简单, 它将我们解析到的bitmap存放到LazyBitmapDrawableResource内部, 然后外界通过get方法就可以获取到一个BitmapDrawable的对象了
数据的展示
class DecodeJob<R> implements DataFetcherGenerator.FetcherReadyCallback,
Runnable,
Comparable<DecodeJob<?>>,
Poolable {
private void decodeFromRetrievedData() {
Resource<R> resource = null;
......// 解析 inputStream 获取资源
if (resource != null) {
// 通知外界资源获取成功了
notifyEncodeAndRelease(resource, currentDataSource);
} else {
......
}
}
private void notifyEncodeAndRelease(Resource<R> resource, DataSource dataSource) {
......
// 1. 回调上层资源准备好了
notifyComplete(result, dataSource);
......
try {
// 2. 将数据缓存到磁盘
if (deferredEncodeManager.hasResourceToEncode()) {
deferredEncodeManager.encode(diskCacheProvider, options);
}
} finally {
...
}
}
private Callback<R> callback;
private void notifyComplete(Resource<R> resource, DataSource dataSource) {
......
// 1.1 从 DecodeJob 的构建中, 我们知道这个 Callback 是一 EngineJob
callback.onResourceReady(resource, dataSource);
}
}
可以看到DecodeJob.decodeFromRetrievedData中, 主要做了两个操作
- 回调
EngineJob.onResourceReady资源准备好了 - 将数据缓存到磁盘
磁盘缓存并非我们关注的终点, 这里我们看看EngineJob.onResourceReady中做了哪些处理
class EngineJob<R> implements DecodeJob.Callback<R>,
Poolable {
@Override
public void onResourceReady(Resource<R> resource, DataSource dataSource) {
synchronized (this) {
this.resource = resource;
this.dataSource = dataSource;
}
notifyCallbacksOfResult();
}
void notifyCallbacksOfResult() {
ResourceCallbacksAndExecutors copy;
Key localKey;
EngineResource<?> localResource;
synchronized (this) {
......
engineResource = engineResourceFactory.build(resource, isCacheable);
hasResource = true;
copy = cbs.copy();
incrementPendingCallbacks(copy.size() + 1);
localKey = key;
localResource = engineResource;
}
// 1. 通知上层 Engine 任务完成了
listener.onEngineJobComplete(this, localKey, localResource);
// 2. 回调给 ImageViewTarget 展示资源
for (final ResourceCallbackAndExecutor entry : copy) {
entry.executor.execute(new CallResourceReady(entry.cb));
}
}
}
EngineJob中也是有两步操作, 一个是通知上层任务完成了, 另一个是回调给ImageViewTarget展示资源
我们先看看上层做了什么处理
public class Engine implements EngineJobListener,
MemoryCache.ResourceRemovedListener,
EngineResource.ResourceListener {
public synchronized void onEngineJobComplete(
EngineJob<?> engineJob, Key key, EngineResource<?> resource) {
if (resource != null) {
// 将加载好的资源添加到内存缓存
if (resource.isCacheable()) {
activeResources.activate(key, resource);
}
}
......
}
}
我们知道在请求发起前是Engine尝试通过内存缓存读, 结束之后再回到Engine添加内存缓存也不足为奇了
接下来我们看看ImageViewTarget展示资源的过程
public abstract class ImageViewTarget<Z> extends ViewTarget<ImageView, Z>
implements Transition.ViewAdapter {
public void onResourceReady(@NonNull Z resource, @Nullable Transition<? super Z> transition) {
// 处理一些 transition 变化, 在构建 Request 时有分析过, 这里不赘述其实现细节了
if (transition == null || !transition.transition(resource, this)) {
setResourceInternal(resource);
} else {
......
}
}
private void setResourceInternal(@Nullable Z resource) {
// 调用了 setResource
setResource(resource);
......
}
}
public class DrawableImageViewTarget extends ImageViewTarget<Drawable> {
protected void setResource(@Nullable Drawable resource) {
// 呈现到 View 上
view.setImageDrawable(resource);
}
}
ImageViewTarget调用了子类重写的setResource方法, 将数据填充进去, 至此一次Glide图像加载就完成了
总结
通过一次流程分析我们得知, 整个Glide图片加载主要有如下几步
-
请求管理器的构建
- 一个
Context对应一个RequestManager
- 一个
-
请求的构建
- 请求的宽高、采样的方式、
transform变化...
- 请求的宽高、采样的方式、
-
通过请求获取资源
-
Engine从内存缓存中查找- 从
ActiveResources缓存中查找 - 从
Cache缓存中查找
- 从
- 内存缓存不存在, 则构建任务执行
- 构建一个
EngineJob描述一个请求任务, 任务类型为DecodeJob-
DecodeJob从diskCache中查找 -
diskCache不存在, 则通过网络请求, 获取数据源 - 通过
Downsampler解析源数据并进行采样压缩获取Bitmap - 对
Bitmap进行transform处理- 构建磁盘缓存的
key
- 构建磁盘缓存的
- 将
transform之后的Bitmap转为Resource回传给上层-
DecodeJob进行磁盘缓存
-
-
- 构建一个
-
Engine对资源进行内存缓存
-
- 传递给
View进行展示
Glide的源码还是真的有点复杂,这还只是最简单的流程,都给我看蒙了,可想而知他内部代码逻辑有多复杂。