关于 Glide
Glide是一个快速高效的Android图片加载库,注重于平滑的滚动。Glide提供了易用的API,高性能、可扩展的图片解码管道(decode pipeline),以及自动的资源池技术。
Glide 支持拉取,解码和展示视频快照,图片,和GIF动画。Glide的Api是如此的灵活,开发者甚至可以插入和替换成自己喜爱的任何网络栈。默认情况下,Glide使用的是一个定制化的基于HttpUrlConnection的栈,但同时也提供了与Google Volley和Square OkHttp快速集成的工具库。
Glide的性能
Glide 充分考虑了Android图片加载性能的两个关键方面:
图片解码速度
解码图片带来的资源压力
为了让用户拥有良好的App使用体验,图片不仅要快速加载,而且还不能因为过多的主线程I/O或频繁的垃圾回收导致页面的闪烁和抖动现象。
Glide使用了多个步骤来确保在Android上加载图片尽可能的快速和平滑:
自动、智能地下采样(downsampling)和缓存(caching),以最小化存储开销和解码次数;
积极的资源重用,例如字节数组和Bitmap,以最小化昂贵的垃圾回收和堆碎片影响;
深度的生命周期集成,以确保仅优先处理活跃的Fragment和Activity的请求,并有利于应用在必要时释放资源以避免在后台时被杀掉。
Glide的使用
Glide 使用简明的流式语法API,这是一个非常棒的设计,因为它允许你在大部分情况下一行代码搞定需求:
Glide.with(fragment)
.load(url)
.into(imageView);
Glide的使用example详解
1、库的引用
dependencies {
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
}
2、混淆文件
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
# for DexGuard only
-keepresourcexmlelements manifest/application/meta-data@value=GlideModule
3、简单使用
// For a simple view:
@Override public void onCreate(Bundle savedInstanceState) {
...
ImageView imageView = (ImageView) findViewById(R.id.my_image_view);
Glide.with(this).load("http://goo.gl/gEgYUd").into(imageView);
}
// For a simple image list:
@Override public View getView(int position, View recycled, ViewGroup container) {
final ImageView myImageView;
if (recycled == null) {
myImageView = (ImageView) inflater.inflate(R.layout.my_image_view, container, false);
} else {
myImageView = (ImageView) recycled;
}
String url = myUrls.get(position);
Glide
.with(myFragment)
.load(url)
.centerCrop()
.placeholder(R.drawable.loading_spinner)
.into(myImageView);
return myImageView;
}
ImageView imageView = new ImageView(this);
String url = "http://www.$$$.com/100.png";
Glide.with(getApplicationContext())//指定上下文环境
.load(url)//指定图片的url
.placeholder(R.mipmap.ic_launcher)//指定未加载成功前显示的图片
.error(R.mipmap.ic_launcher)//指定加载失败时显示的图片
.override(300,300)//指定图片的尺寸
.fitCenter()//指定图片的缩放类型 缩放居中显示 完全显示全部图像,可能不被填满
.centerCrop()//同上 填充整个view,会裁剪图片,可能不完全显示全部图像
.skipMemoryCache(true)//是否跳过内存缓存
.diskCacheStrategy(DiskCacheStrategy.NONE)//跳过磁盘缓存
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)//缓存原来全分辨率的图像
.diskCacheStrategy(DiskCacheStrategy.DATA)//缓存最终的图像
.diskCacheStrategy(DiskCacheStrategy.ALL)//缓存所有版本图像
.priority(Priority.HIGH)//指定加载优先级
.into(imageView);
Glide的加载图片原理分析
首先大概了解图片加载整体的流程:
Glide.with(getApplicationContext())
进入第一段代码,Glide类中查看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 View view) {
return getRetriever(view.getContext()).get(view);
}
可以看到 Glide 的 with 方法提供了好几种参数的重载方法方便使用。同时都用到了 getRetriever()方法,查看 getRetriever() 方法都做了什么:
@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
// Context could be null for other reasons (ie the user passes in null), but in practice it will
// only occur due to errors with the Fragment lifecycle.
//检测是否context为空
Preconditions.checkNotNull(
context,
"You cannot start a load on a not yet attached View or a Fragment where getActivity() "
+ "returns null (which usually occurs when getActivity() is called before the Fragment "
+ "is attached or after the Fragment is destroyed).");
return Glide.get(context).getRequestManagerRetriever();
}
这里看到 getRetriever() 方法主要去获取 RequestManagerRetriever 类?
进入到 Glide.get(context) 方法;
@NonNull
public static Glide get(@NonNull Context context) { // 单例获取
if (glide == null) {
GeneratedAppGlideModule annotationGeneratedModule =
getAnnotationGeneratedGlideModules(context.getApplicationContext());
synchronized (Glide.class) {
if (glide == null) {
checkAndInitializeGlide(context, annotationGeneratedModule); // 初始化 Glide
}
}
}
return glide;
}
这里 get 方法主要获取了 Glide 的单例对象,同时初始化了 Glide;
@GuardedBy("Glide.class")
private static void checkAndInitializeGlide(
@NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
// In the thread running initGlide(), one or more classes may call Glide.get(context).
// Without this check, those calls could trigger infinite recursion.
if (isInitializing) {
throw new IllegalStateException(
"You cannot call Glide.get() in registerComponents(),"
+ " use the provided Glide instance instead");
}
isInitializing = true;
initializeGlide(context, generatedAppGlideModule); // 初始化动作
isInitializing = false;
}
@GuardedBy("Glide.class")
private static void initializeGlide(
@NonNull Context context, @Nullable GeneratedAppGlideModule generatedAppGlideModule) {
initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
}
继续调用 initializeGlide 方法进行初始化;
@GuardedBy("Glide.class")
@SuppressWarnings("deprecation")
private static void initializeGlide(
@NonNull Context context,
@NonNull GlideBuilder builder,
@Nullable GeneratedAppGlideModule annotationGeneratedModule) {
Context applicationContext = context.getApplicationContext(); // 获取上下文五年环境
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;
}
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "AppGlideModule excludes manifest GlideModule: " + current);
}
iterator.remove();
}
}
if (Log.isLoggable(TAG, Log.DEBUG)) {
for (com.bumptech.glide.module.GlideModule glideModule : manifestModules) {
Log.d(TAG, "Discovered GlideModule from manifest: " + glideModule.getClass());
}
}
RequestManagerRetriever.RequestManagerFactory factory =
annotationGeneratedModule != null
? annotationGeneratedModule.getRequestManagerFactory()
: null;
builder.setRequestManagerFactory(factory);// 工厂模式
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
module.applyOptions(applicationContext, builder);
}
if (annotationGeneratedModule != null) {
annotationGeneratedModule.applyOptions(applicationContext, builder);
}
Glide glide = builder.build(applicationContext);// 构造初始数据
for (com.bumptech.glide.module.GlideModule module : manifestModules) {
try {
module.registerComponents(applicationContext, glide, glide.registry);
} catch (AbstractMethodError e) {
throw new IllegalStateException(
"Attempting to register a Glide v3 module. If you see this, you or one of your"
+ " dependencies may be including Glide v3 even though you're using Glide v4."
+ " You'll need to find and remove (or update) the offending dependency."
+ " The v3 module name is: "
+ module.getClass().getName(),
e);
}
}
if (annotationGeneratedModule != null) {
annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
}
applicationContext.registerComponentCallbacks(glide);
Glide.glide = glide;
}
initializeGlide 继续会通过工厂模式构造初始的数据,build 方法进行数据的初始化;
@NonNull
Glide build(@NonNull Context context) {
if (sourceExecutor == null) { //加载source 线程池
sourceExecutor = GlideExecutor.newSourceExecutor();
}
if (diskCacheExecutor == null) {// 缓存线程池
diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
}
if (animationExecutor == null) {// 动画线程池
animationExecutor = GlideExecutor.newAnimationExecutor();
}
if (memorySizeCalculator == null) {// 计算存储大小工具
memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
}
if (connectivityMonitorFactory == null) {
connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
}
if (bitmapPool == null) {// bitmap 池
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
engine =
new Engine(
memoryCache,
diskCacheFactory,
diskCacheExecutor,
sourceExecutor,
GlideExecutor.newUnlimitedSourceExecutor(),
animationExecutor,
isActiveResourceRetentionAllowed);
}
if (defaultRequestListeners == null) {// 请求监听
defaultRequestListeners = Collections.emptyList();
} else {
defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
}
RequestManagerRetriever requestManagerRetriever =
new RequestManagerRetriever(requestManagerFactory); // 创建 RequestManagerRetriever
return new Glide(
context,
engine,
memoryCache,
bitmapPool,
arrayPool,
requestManagerRetriever,
connectivityMonitorFactory,
logLevel,
defaultRequestOptionsFactory,
defaultTransitionOptions,
defaultRequestListeners,
isLoggingRequestOriginsEnabled,
isImageDecoderEnabledForBitmaps);
}
}
可以方法看到初始化了一些线程池,最终将相关实例对象赋值到 Glide 对象中,并进行返回;其中就包含了 RequestManagerRetriever 实例对象;
接下来看看 RequestManagerRetriever是做什么的呢?
RequestManagerRetriever
public class RequestManagerRetriever implements Handler.Callback {
private volatile RequestManager applicationManager;
@SuppressWarnings("deprecation")
@VisibleForTesting
final Map<android.app.FragmentManager, RequestManagerFragment> pendingRequestManagerFragments =
new HashMap<>(); // RequestManagerFragment 集合
/** Pending adds for SupportRequestManagerFragments. */
@VisibleForTesting
final Map<FragmentManager, SupportRequestManagerFragment> pendingSupportRequestManagerFragments =
new HashMap<>(); // SupportRequestManagerFragment 集合
/** Main thread handler to handle cleaning up pending fragment maps. */
private final Handler handler;
private final RequestManagerFactory factory;
// Objects used to find Fragments and Activities containing views.
private final ArrayMap<View, Fragment> tempViewToSupportFragment = new ArrayMap<>();
private final ArrayMap<View, android.app.Fragment> tempViewToFragment = new ArrayMap<>();
private final Bundle tempBundle = new Bundle();
public RequestManagerRetriever(@Nullable RequestManagerFactory factory) { // 创建Handler
this.factory = factory != null ? factory : DEFAULT_FACTORY;
handler = new Handler(Looper.getMainLooper(), this /* Callback */);
}
}
@NonNull
public RequestManager get(@NonNull Context context) { // 获取 context 的 RequestManager
if (context == null) {
throw new IllegalArgumentException("You cannot start a load on a null Context");
} else if (Util.isOnMainThread() && !(context instanceof Application)) {
if (context instanceof FragmentActivity) {
return get((FragmentActivity) context);
} else if (context instanceof Activity) {
return get((Activity) context);
} else if (context instanceof ContextWrapper
// Only unwrap a ContextWrapper if the baseContext has a non-null application context.
// Context#createPackageContext may return a Context without an Application instance,
// in which case a ContextWrapper may be used to attach one.
&& ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
return get(((ContextWrapper) context).getBaseContext());
}
}
return getApplicationManager(context);
}
private RequestManager getApplicationManager(@NonNull Context context) {}// 获取 application 对应的 RequestManager
public RequestManager get(@NonNull Fragment fragment) {} // Fragment对应的 RequestManager
public RequestManager get(@NonNull Activity activity) {}// Activity 对应的 RequestManager
public RequestManager get(@NonNull View view) {}// View对应的 RequestManager
RequestManagerRetriever 实现了 Handler 类,handleMessage 对内部维护的 RequestManagerFragment 进行移除处理,同时提供获取对应参数的 RequestManager 方法 ;
查看 RequestManagerRetriever 的 handlerMessage 方法:
@Override
public boolean handleMessage(Message message) {
boolean handled = true;
Object removed = null;
Object key = null;
switch (message.what) {
case ID_REMOVE_FRAGMENT_MANAGER:
android.app.FragmentManager fm = (android.app.FragmentManager) message.obj;
key = fm;
removed = pendingRequestManagerFragments.remove(fm); //
break;
case ID_REMOVE_SUPPORT_FRAGMENT_MANAGER:
FragmentManager supportFm = (FragmentManager) message.obj;
key = supportFm;
removed = pendingSupportRequestManagerFragments.remove(supportFm);
break;
default:
handled = false;
break;
}
if (handled && removed == null && Log.isLoggable(TAG, Log.WARN)) {
Log.w(TAG, "Failed to remove expected request manager fragment, manager: " + key);
}
return handled;
}
RequestManagerRetriever 通过 Handler 发送消息维护内部的 RequestManagerFragment;
RequestManagerRetriever 同时用来生产 RequestManager;
了解前先查看 RequestManagerFragment
RequestManagerFragment
@Deprecated
public class RequestManagerFragment extends Fragment {
private static final String TAG = "RMFragment";
private final ActivityFragmentLifecycle lifecycle; // ActivityFragmentLifecycle 生命周期
private final RequestManagerTreeNode requestManagerTreeNode =
new FragmentRequestManagerTreeNode();
@SuppressWarnings("deprecation")
private final Set<RequestManagerFragment> childRequestManagerFragments = new HashSet<>();
@Nullable private RequestManager requestManager;
@SuppressWarnings("deprecation")
@Nullable
private RequestManagerFragment rootRequestManagerFragment;
@Nullable private Fragment parentFragmentHint;
public RequestManagerFragment() {
this(new ActivityFragmentLifecycle());
}
@VisibleForTesting
@SuppressLint("ValidFragment")
RequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
this.lifecycle = lifecycle;
}
/**
* Sets the current {@link com.bumptech.glide.RequestManager}.
*
* @param requestManager The request manager to use.
*/
public void setRequestManager(@Nullable RequestManager requestManager) {
this.requestManager = requestManager;
}
@NonNull
ActivityFragmentLifecycle getGlideLifecycle() {
return lifecycle;
}
/** Returns the current {@link com.bumptech.glide.RequestManager} or null if none exists. */
@Nullable
public RequestManager getRequestManager() {
return requestManager;
}
}
RequestManagerFragment 主要是为了获取 RequestManager 实例,同时维护了 ActivityFragment 的生命周期;
接下来查看 RequestManager 类:
RequestManager
public class RequestManager
implements ComponentCallbacks2, LifecycleListener, ModelTypes<RequestBuilder<Drawable>> {
private static final RequestOptions DECODE_TYPE_BITMAP = decodeTypeOf(Bitmap.class).lock();
private static final RequestOptions DECODE_TYPE_GIF = decodeTypeOf(GifDrawable.class).lock();
private static final RequestOptions DOWNLOAD_ONLY_OPTIONS =
diskCacheStrategyOf(DiskCacheStrategy.DATA).priority(Priority.LOW).skipMemoryCache(true);
protected final Glide glide;
protected final Context context;
@SuppressWarnings("WeakerAccess")
@Synthetic
final Lifecycle lifecycle; // 生命周期
@GuardedBy("this")
private final RequestTracker requestTracker;
@GuardedBy("this")
private final RequestManagerTreeNode treeNode;
@GuardedBy("this")
private final TargetTracker targetTracker = new TargetTracker();
private final Runnable addSelfToLifecycle =
new Runnable() {
@Override
public void run() {
lifecycle.addListener(RequestManager.this); // 绑定生命周期
}
};
private final Handler mainHandler = new Handler(Looper.getMainLooper());
private final ConnectivityMonitor connectivityMonitor;
private final CopyOnWriteArrayList<RequestListener<Object>> defaultRequestListeners;
@GuardedBy("this")
private RequestOptions requestOptions;
private boolean pauseAllRequestsOnTrimMemoryModerate;
public RequestManager(
@NonNull Glide glide,
@NonNull Lifecycle lifecycle,
@NonNull RequestManagerTreeNode treeNode,
@NonNull Context context) {
this(
glide,
lifecycle,
treeNode,
new RequestTracker(),
glide.getConnectivityMonitorFactory(),
context);
}
// Our usage is safe here.
@SuppressWarnings("PMD.ConstructorCallsOverridableMethod")
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
this.glide = glide;
this.lifecycle = lifecycle;
this.treeNode = treeNode;
this.requestTracker = requestTracker;
this.context = context;
connectivityMonitor =
factory.build(
context.getApplicationContext(),
new RequestManagerConnectivityListener(requestTracker));// 连接监控
if (Util.isOnBackgroundThread()) {
mainHandler.post(addSelfToLifecycle);
} else {
lifecycle.addListener(this);
}
lifecycle.addListener(connectivityMonitor);
defaultRequestListeners =
new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
setRequestOptions(glide.getGlideContext().getDefaultRequestOptions()); // 请求监听
glide.registerRequestManager(this);
}
}
RequestManager 初始化主要和 Glide 、lifecycle 生命周期进行关联;
简单看完了 RequestManagerFragment 和 RequestManager;继续来分析 Application、Activity、Fragment、View 如何获取对应的 RequestManager 并关联对应生命周期的?
Application --- 传入 ApplicationLifecycle 生命周期,创建对应的 RequestManager;
@NonNull
private RequestManager getApplicationManager(@NonNull Context context) {// 获取 application 的 RequestManager
// Either an application context or we're on a background thread.
if (applicationManager == null) {
synchronized (this) {
if (applicationManager == null) {
// TODO(b/27524013): Factor out this Glide.get() call.
Glide glide = Glide.get(context.getApplicationContext());
applicationManager =
factory.build(
glide,
new ApplicationLifecycle(), // Application 的生命周期
new EmptyRequestManagerTreeNode(),
context.getApplicationContext()); // 创建 RequestManager
}
}
}
return applicationManager;
}
Activity -- 如果在后台则调用到 Application 对应 RequestManager 获取的办法,否则通过创建 FragmentManager 调用 fragmentGet 方法
@SuppressWarnings("deprecation")
@NonNull
public RequestManager get(@NonNull Activity activity) { // Activity 对应的 RequestManager
if (Util.isOnBackgroundThread()) { // 在后台
return get(activity.getApplicationContext());
} else {
assertNotDestroyed(activity);
android.app.FragmentManager fm = activity.getFragmentManager();
return fragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
}
}
@Deprecated
@NonNull
private RequestManager fragmentGet(
@NonNull Context context,
@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
// TODO(b/27524013): Factor out this Glide.get() call.
Glide glide = Glide.get(context);
requestManager =
factory.build(
glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);
}
return requestManager;
}
此处传入的生命周期为 RequestManagerFragment 调用 getGlideLifecycle 方法;而 RequestManagerFragment 获取的就是 Activity 的生命周期,此时 requestManager 和 Activity 生命周期进行了关联
Fragment -- 和 Activity 生命周期类似;
@NonNull
public RequestManager get(@NonNull Fragment fragment) { // Fragment对应的 RequestManager
Preconditions.checkNotNull(
fragment.getContext(),
"You cannot start a load on a fragment before it is attached or after it is destroyed");
if (Util.isOnBackgroundThread()) {
return get(fragment.getContext().getApplicationContext());
} else {
FragmentManager fm = fragment.getChildFragmentManager();
return supportFragmentGet(fragment.getContext(), fm, fragment, fragment.isVisible());
}
}
View -- 根据 View 对应的 context 分别对应获取 RequestManager
public RequestManager get(@NonNull View view) {// View对应的 RequestManager
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());
if (activity == null) {
return get(view.getContext().getApplicationContext());
}
if (activity instanceof FragmentActivity) {
Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
return fragment != null ? get(fragment) : get((FragmentActivity) activity);
}
android.app.Fragment fragment = findFragment(view, activity);
if (fragment == null) {
return get(activity);
}
return get(fragment);
}
看完了以上,我们大概了解 RequestManagerRetriever 类主要就是通过 RequestManager 类和对应 Context 参数生命周期进行了绑定;
从而 Gilde.with 方法实际就与传参的生命周期就行了绑定;
Glide.with().load(url);通过 RequestManager 进行 url 的加载;
@NonNull
@CheckResult
@Override
public RequestBuilder<Drawable> load(@Nullable String string) {
return asDrawable().load(string);
}
@NonNull
@CheckResult
public RequestBuilder<Drawable> asDrawable() {
return as(Drawable.class);
}
@NonNull
@CheckResult
public <ResourceType> RequestBuilder<ResourceType> as(
@NonNull Class<ResourceType> resourceClass) {
return new RequestBuilder<>(glide, this, resourceClass, context);
}
创建 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();
initRequestListeners(requestManager.getDefaultRequestListeners());// 加载的监听
apply(requestManager.getDefaultRequestOptions());
}
RequestBuilder 构造方法初始化相关变量;此时 transcodeClass 则为 asDrawable() 方法传进来的Drawable.class;调用到 requestManager.getDefaultTransitionOptions(transcodeClass) 方法生成的 transitionOptions ;
@NonNull
<T> TransitionOptions<?, T> getDefaultTransitionOptions(Class<T> transcodeClass) {
return glide.getGlideContext().getDefaultTransitionOptions(transcodeClass);
}
获取 GlideContext 类,并调用 getDefaultTransitionOptions 方法;
public GlideContext(
@NonNull Context context,
@NonNull ArrayPool arrayPool,
@NonNull Registry registry,
@NonNull ImageViewTargetFactory imageViewTargetFactory,
@NonNull RequestOptionsFactory defaultRequestOptionsFactory,
@NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
@NonNull List<RequestListener<Object>> defaultRequestListeners,
@NonNull Engine engine,
boolean isLoggingRequestOriginsEnabled,
int logLevel) {
super(context.getApplicationContext());
this.arrayPool = arrayPool;
this.registry = registry;
this.imageViewTargetFactory = imageViewTargetFactory;
this.defaultRequestOptionsFactory = defaultRequestOptionsFactory;
this.defaultRequestListeners = defaultRequestListeners;
this.defaultTransitionOptions = defaultTransitionOptions;
this.engine = engine;
this.isLoggingRequestOriginsEnabled = isLoggingRequestOriginsEnabled;
this.logLevel = logLevel;
}
static final TransitionOptions<?, ?> DEFAULT_TRANSITION_OPTIONS =
new GenericTransitionOptions<>();
private final Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions;
@NonNull
public <T> TransitionOptions<?, T> getDefaultTransitionOptions(@NonNull Class<T> transcodeClass) {
TransitionOptions<?, ?> result = defaultTransitionOptions.get(transcodeClass);
if (result == null) {
for (Entry<Class<?>, TransitionOptions<?, ?>> value : defaultTransitionOptions.entrySet()) {
if (value.getKey().isAssignableFrom(transcodeClass)) {
result = value.getValue();
}
}
}
if (result == null) {
result = DEFAULT_TRANSITION_OPTIONS;
}
return (TransitionOptions<?, T>) result;
}
getDefaultTransitionOptions 方法主要为了从 GlideContext 中获取到TransitionOptions实列,否则则取默认的 TransitionOptions 实例;那么TransitionOptions是干嘛的呢?
TransitionOptions
/**
* A base class for setting a transition to use on a resource when a load completes.
*
* @param <CHILD> The implementation of this class to return to chain methods.
* @param <TranscodeType> The type of resource that will be animated.
*/
public abstract class TransitionOptions<
CHILD extends TransitionOptions<CHILD, TranscodeType>, TranscodeType>
implements Cloneable {
A base class for setting a transition to use on a resource when a load completes.
意思大概就是对资源加载转换的一个工具,个人认为类似于解码器东西;
获取到 TransitionOptions 之后, 最后 RequestBuilder 调用 apply 方法;
@NonNull
@CheckResult
@Override
public RequestBuilder<TranscodeType> apply(@NonNull BaseRequestOptions<?> requestOptions) {
Preconditions.checkNotNull(requestOptions);
return super.apply(requestOptions);
}
@NonNull
@CheckResult
public T apply(@NonNull BaseRequestOptions<?> o) {
if (isAutoCloneEnabled) {
return clone().apply(o);
}
BaseRequestOptions<?> other = o;
if (isSet(other.fields, SIZE_MULTIPLIER)) {
sizeMultiplier = other.sizeMultiplier;
}
if (isSet(other.fields, USE_UNLIMITED_SOURCE_GENERATORS_POOL)) {
useUnlimitedSourceGeneratorsPool = other.useUnlimitedSourceGeneratorsPool;
}
if (isSet(other.fields, USE_ANIMATION_POOL)) {
useAnimationPool = other.useAnimationPool;
}
if (isSet(other.fields, DISK_CACHE_STRATEGY)) {
diskCacheStrategy = other.diskCacheStrategy;
}
if (isSet(other.fields, PRIORITY)) {
priority = other.priority;
}
if (isSet(other.fields, ERROR_PLACEHOLDER)) {
errorPlaceholder = other.errorPlaceholder;
errorId = 0;
fields &= ~ERROR_ID;
}
if (isSet(other.fields, ERROR_ID)) {
errorId = other.errorId;
errorPlaceholder = null;
fields &= ~ERROR_PLACEHOLDER;
}
if (isSet(other.fields, PLACEHOLDER)) {
placeholderDrawable = other.placeholderDrawable;
placeholderId = 0;
fields &= ~PLACEHOLDER_ID;
}
if (isSet(other.fields, PLACEHOLDER_ID)) {
placeholderId = other.placeholderId;
placeholderDrawable = null;
fields &= ~PLACEHOLDER;
}
if (isSet(other.fields, IS_CACHEABLE)) {
isCacheable = other.isCacheable;
}
if (isSet(other.fields, OVERRIDE)) {
overrideWidth = other.overrideWidth;
overrideHeight = other.overrideHeight;
}
if (isSet(other.fields, SIGNATURE)) {
signature = other.signature;
}
if (isSet(other.fields, RESOURCE_CLASS)) {
resourceClass = other.resourceClass;
}
if (isSet(other.fields, FALLBACK)) {
fallbackDrawable = other.fallbackDrawable;
fallbackId = 0;
fields &= ~FALLBACK_ID;
}
if (isSet(other.fields, FALLBACK_ID)) {
fallbackId = other.fallbackId;
fallbackDrawable = null;
fields &= ~FALLBACK;
}
if (isSet(other.fields, THEME)) {
theme = other.theme;
}
if (isSet(other.fields, TRANSFORMATION_ALLOWED)) {
isTransformationAllowed = other.isTransformationAllowed;
}
if (isSet(other.fields, TRANSFORMATION_REQUIRED)) {
isTransformationRequired = other.isTransformationRequired;
}
if (isSet(other.fields, TRANSFORMATION)) {
transformations.putAll(other.transformations);
isScaleOnlyOrNoTransform = other.isScaleOnlyOrNoTransform;
}
if (isSet(other.fields, ONLY_RETRIEVE_FROM_CACHE)) {
onlyRetrieveFromCache = other.onlyRetrieveFromCache;
}
// Applying options with dontTransform() is expected to clear our transformations.
if (!isTransformationAllowed) {
transformations.clear();
fields &= ~TRANSFORMATION;
isTransformationRequired = false;
fields &= ~TRANSFORMATION_REQUIRED;
isScaleOnlyOrNoTransform = true;
}
fields |= other.fields;
options.putAll(other.options);
return selfOrThrowIfLocked();
}
这里看到对用户设置的相关内容进行了赋值操作,例如placeholderId 、overrideWidth 、overrideHeight等。
接下来的 RequestBuilder 的 load() 进行相关的初始化操作;
@NonNull
@Override
@CheckResult
public RequestBuilder<TranscodeType> load(@Nullable String string) {
return loadGeneric(string);
}
@NonNull
private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
this.model = model;
isModelSet = true;
return this;
}
本篇文章先讲到这里,对Glide.with().load(url)进行了梳理,总结下主要做了哪些工作:
1 获取 RequestManager 创建绑定相关的生命周期(Application、Activity、Fragment、View)
2 初始化相关图片加载的数据信息以及参数;
最后,通过 UML 大致描述相关类之间的联系
接下来我们将继续在探究Glide的运行原理(2)
)中接着对Glide.with().load(url).into(view)的into方法进行梳理