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
的源码还是真的有点复杂,这还只是最简单的流程,都给我看蒙了,可想而知他内部代码逻辑有多复杂。
网友评论