Glide 作为著名的图片加载框架,几乎每一个项目都使用到。笔者尝试通过别人的博客来了解 Glide 原理,但是每次都是看着看着就懵逼了,不是因为别人写的不好,而是 Glide 实在是太复杂了,于是决定自己撸一遍,加深印象。纸上得来终觉浅,绝知此事要躬行。
因为 Glide 太庞大了,做不到面面俱到,所以笔者主要先梳理主干核心原理,后续持续整理。本文源码分析基于4.15.0,就从最基础的调用 Glide.with(context).load(url).into(imageView) 来入手,把主流程最核心的源码整理并且标注、总结。
该篇是Glide.with
类 | 作用 |
Glide | 负责线程池、缓存的构建 |
RequestManagerRetriever | 负责获取RequestManager |
SupportRequestManagerFragment | 用户接收和转发生命周期 |
RequestManager | 用于请求管理 |
第1步,从 Glide.with 出发,可以看到Glide.with 有很多重载方法,目的是返回一个RequestManager。(Glide.java)
-
- //传递Context
- public static RequestManager with(@NonNull Context context) {
- return getRetriever(context).get(context);
- }
-
- // 传递FragmentActivity
- public static RequestManager with(@NonNull FragmentActivity activity) {
- return getRetriever(activity).get(activity);
- }
-
- // 传递Fragment
- public static RequestManager with(@NonNull Fragment fragment) {
- return getRetriever(fragment.getContext()).get(fragment);
- }
-
- //传递View
- public static RequestManager with(@NonNull View view) {
- return getRetriever(view.getContext()).get(view);
- }
-
- ......
第2步 Glide.with 里面会调用 getRetriever方法,getRetriever() 先会调用 Glide.get(),Glide.get 会调用checkAndInitializeGlide 方法,注意会传递一个APT生成的 GeneratedAppGlideModuleImpl(Glide.java)
- private static RequestManagerRetriever getRetriever(@Nullable Context context) {
- // 省略...
- return Glide.get(context).getRequestManagerRetriever();
- }
- //双层检测单例模式
- public static Glide get(@NonNull Context context) {
- if (glide == null) {
- //getAnnotationGeneratedGlideModules 内部通过。
- //Class.forName("com.bumptech.glide.GeneratedAppGlideModuleImpl")
- //拿到GeneratedAppGlideModuleImpl 并且作为参数传递
- GeneratedAppGlideModule annotationGeneratedModule =
- getAnnotationGeneratedGlideModules(context.getApplicationContext());
- synchronized (Glide.class) {
- if (glide == null) {
- checkAndInitializeGlide(context, annotationGeneratedModule);
- }
- }
- }
- return glide;
- }
-
最终来到Glide.initializeGlide,GeneratedAppGlideModuleImpl 的作用先记录,后续再慢慢了解,因为 Glide 内容实在太庞大了,每一个细节都要掌握无法梳理主流程(Glide.java)
- private static void initializeGlide(
- @NonNull Context context,
- @NonNull GlideBuilder builder,
- @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
- //1. 获取应用AppContext,最终是用来构建Glide的
- Context applicationContext = context.getApplicationContext();
- //2.这里通过传递进来的 GeneratedAppGlideModuleImpl 调用 getExcludedModuleClasses
- List
manifestModules = Collections.emptyList(); - if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
- manifestModules = new ManifestParser(applicationContext).parse();
- }
-
- if (annotationGeneratedModule != null
- && !annotationGeneratedModule.getExcludedModuleClasses().isEmpty()) {
- Set
> excludedModuleClasses = annotationGeneratedModule.getExcludedModuleClasses(); - Iterator
iterator = manifestModules.iterator(); - while (iterator.hasNext()) {
- 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 (GlideModule glideModule : manifestModules) {
- Log.d(TAG, "Discovered GlideModule from manifest: " + glideModule.getClass());
- }
- }
-
- //3.这里通过传递进来的 GeneratedAppGlideModuleImpl 获取 RequestManagerRetriever.RequestManagerFactory
- RequestManagerRetriever.RequestManagerFactory factory =
- annotationGeneratedModule != null
- ? annotationGeneratedModule.getRequestManagerFactory()
- : null;
- //4.将拿到的工厂添加到GlideBuilder
- builder.setRequestManagerFactory(factory);
- for (GlideModule module : manifestModules) {
- module.applyOptions(applicationContext, builder);
- }
- //5.这里通过传递进来的 GeneratedAppGlideModuleImpl 调用 applyOptions
- if (annotationGeneratedModule != null) {
- annotationGeneratedModule.applyOptions(applicationContext, builder);
- }
- //6.通过GlideBuilder 建造者模式生成 Glide
- Glide glide = builder.build(applicationContext, manifestModules, annotationGeneratedModule);
- applicationContext.registerComponentCallbacks(glide);
- //7. 将构建出来的glide 赋值给 Glide 的静态变量
- Glide.glide = glide;
- }
第3步,我们看到了有一个GlideBuilder 来生成Glide,这里有一个地方非常关键:GliderBuilder 来构建Glide,传递的Context 是applicationContext!!!, 你外部使用activity, 这里都会getApplicationContext 传入!!!
- Glide build(
- @NonNull Context context,
- List
manifestModules, - AppGlideModule annotationGeneratedGlideModule) {
- //实例化网络请求线程池
- 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());
- }
- //实例化内存缓存 LruCache
- if (memoryCache == null) {
- memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
- }
- //实例化磁盘缓存工厂
- if (diskCacheFactory == null) {
- diskCacheFactory = new InternalCacheDiskCacheFactory(context);
- }
- //构建执行缓存策略跟线程池的引擎
- if (engine == null) {
- engine =
- new Engine(
- memoryCache,
- diskCacheFactory,
- diskCacheExecutor,
- sourceExecutor,
- GlideExecutor.newUnlimitedSourceExecutor(),
- animationExecutor,
- isActiveResourceRetentionAllowed);
- }
-
- if (defaultRequestListeners == null) {
- defaultRequestListeners = Collections.emptyList();
- } else {
- defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
- }
-
- GlideExperiments experiments = glideExperimentsBuilder.build();
- //实例化RequestManagerRetriever 请求管理类
- RequestManagerRetriever requestManagerRetriever =
- new RequestManagerRetriever(requestManagerFactory);
-
- //实例化Glide
- return new Glide(
- context,
- engine,
- memoryCache,
- bitmapPool,
- arrayPool,
- requestManagerRetriever,
- connectivityMonitorFactory,
- logLevel,
- defaultRequestOptionsFactory,
- defaultTransitionOptions,
- defaultRequestListeners,
- manifestModules,
- annotationGeneratedGlideModule,
- experiments);
- }
第4步,所以首次调用 Glide.get() 会把 Glide 构建完成,那么调用 Glide 的 getRequestManagerRetriver()就能拿到 RequestManagerRetriver对象。下面看看RequestManagerRetriver.get() 方法,也是有很多重载方法。
先看下RequestManagerRetriver.get(Context context), 可以看到如果不在主线程或者Context为AppContext,那么调用的是getApplicationManager
- @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)) {//1.主线程并且context不为Application
- if (context instanceof FragmentActivity) {
- //2.如果是FragmentActivity
- return get((FragmentActivity) context);
- } else if (context instanceof Activity) {
- //3.如果是Activity
- return get((Activity) context);
- } else if (context instanceof ContextWrapper
- && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
- //4.如果是ContextWrapper,并且baseContext的AppContext 不为空
- return get(((ContextWrapper) context).getBaseContext());
- }
- }
- //5.不在主线程或者context为AppContext 调用getApplicationManager
- return getApplicationManager(context);
- }
第5步,先看getApplicationManager(context) 构建applicationManager的对象, 这个是App层级的RequestManager。 (RequestManagerReceiver.java)
- private RequestManager getApplicationManager(@NonNull Context context) {
- // Either an application context or we're on a background thread.
- if (applicationManager == null) {
- synchronized (this) {
- if (applicationManager == null) {
- //使用AppContext 作为参数拿Glide
- Glide glide = Glide.get(context.getApplicationContext());
- applicationManager =
- factory.build(
- glide,
- new ApplicationLifecycle(),//注意:这里是ApplicationLifecycle
- new EmptyRequestManagerTreeNode(),
- context.getApplicationContext());
- }
- }
- }
-
- return applicationManager;//返回RequestManager
- }
第6步,再看看传递Activity 的情况, 最终会调用FragmentGet 生成一个Fragment 来监听生命周期。这里是最重要的一个方法
- public RequestManager get(@NonNull Activity activity) {
- if (Util.isOnBackgroundThread()) {
- return get(activity.getApplicationContext());
- } else if (activity instanceof FragmentActivity) {
- return get((FragmentActivity) activity);
- } else {
- assertNotDestroyed(activity);
- frameWaiter.registerSelf(activity);
- android.app.FragmentManager fm = activity.getFragmentManager();
- //注意:调用FragmentGet,这里会生成一个Fragment 用来监听生命周期
- return fragmentGet(activity, fm, /* parentHint= */ null, isActivityVisible(activity));
- }
- }
第7步 , fragmentGet 方法生成空白的Fragment,该Fragment 是用来管理请求的生命周期的,并且会和RequestManagerFactory工厂生成的RequestManager 绑定。
- private RequestManager fragmentGet(
- @NonNull Context context,
- @NonNull android.app.FragmentManager fm,
- @Nullable android.app.Fragment parentHint,
- boolean isParentVisible) {
- //1. 通过getRequestManagerFragment生成一个空白的Fragment,用来管理请求的生命周期,核心方法!!
- RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
- RequestManager requestManager = current.getRequestManager();
- //2. 如果FragmentManager,为空,就用RequestManagerFactory工厂生成一个并且设给RequestManagerFragment
- if (requestManager == null) {
- Glide glide = Glide.get(context);
- requestManager =
- factory.build(
- glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
- if (isParentVisible) {
- requestManager.onStart();
- }
- current.setRequestManager(requestManager);
- }
- //3. 返回RequestManager
- return requestManager;
- }
第8步 在看工厂如何生成FragmentManager 之前,先看看如何生成空白的Fragment——RequestManagerFragment,因为这个RequestManagerFragment最终要和RequestManager 绑定的。
- private RequestManagerFragment getRequestManagerFragment(
- @NonNull final android.app.FragmentManager fm, @Nullable android.app.Fragment parentHint) {
- //1. 先缓存中取
- RequestManagerFragment current = pendingRequestManagerFragments.get(fm);
- //2.缓存里面没有,再通过 TAG 从FragmentManager 里拿
- if (current == null) {
- current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
- //3. 缓存没有,通过TAG 也拿不到,就初始化一个新的
- if (current == null) {
- current = new RequestManagerFragment();
- current.setParentFragmentHint(parentHint);
- //4. 先放入缓存,以免下一次Glide请求会再生成一个空白的Fragment
- pendingRequestManagerFragments.put(fm, current);
- //5. 通过当前 Activity的 FragmentManager 开始提交添加一个 Fragment容器
- fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
- //6. 这个空白的Fragment 添加到 FragmentManager 成功,通过 Handler 发送一个消息,清理缓存
- handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
- }
- }
- return current;
- }
上面的 getRequestManagerFragment 有一个很重要的点:采用了双重检测保证宿主、空白Fragment、RequestManager 一一对应
第一重保障:使用Map
第二重保障:通过Handler 发送消息让空白的Fragment 马上添加到FragmentManager
FragmentManager 的事务本来就是通过Handler 发送消息来实现,通过Handler 发送消息有可能不会被马上执行,倘若空白的Fragment的消息一直在等待,那么下一次Glide请求就会再生成一个空白的Fragment。而通过Handler 发送删除消息,可以让空白的Fragment添加到FragmentManager马上执行并且清空缓存,这样下一次Glide 请求到来的时候,从FragmentManager的TAG 就能拿到Fragment, 不会再创建。
第9步,我们再回过头来看看怎样通过工厂RequestManagerFactory 来生成RequestManager的
- private static final RequestManagerFactory DEFAULT_FACTORY =
- new RequestManagerFactory() {
- @NonNull
- @Override
- public RequestManager build(
- @NonNull Glide glide,
- @NonNull Lifecycle lifecycle,
- @NonNull RequestManagerTreeNode requestManagerTreeNode,
- @NonNull Context context) {
- //工厂里也是new 一个 RequestManager
- return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
- }
- };
第10步,RequestManager 初始化,监听lifecycle的生命周期。而这个lifecycl就是空白Fragment里的ActivityFragmentLifecycle
- 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));
- glide.registerRequestManager(this);
- if (Util.isOnBackgroundThread()) {
- Util.postOnUiThread(addSelfToLifecycle);
- } else {
- lifecycle.addListener(this);//this 就是RequestManager 因此RequestManager就会监听Lifecycle生命周期
- }
- lifecycle.addListener(connectivityMonitor);
-
- defaultRequestListeners =
- new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
- setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
- }
-
- //Requestmanager 已经监听了空白Fragment的lifecycle
- @Override
- public synchronized void onStart() {
- resumeRequests();//恢复请求
- targetTracker.onStart();
- }
-
-
- @Override
- public synchronized void onStop() {
- pauseRequests();//暂停请求
- targetTracker.onStop();
- }
- public class RequestManagerFragment extends Fragment {
- private static final String TAG = "RMFragment";
- private final ActivityFragmentLifecycle lifecycle;
-
- ......
- @Override
- public void onStart() {
- super.onStart();
- lifecycle.onStart();//转发生命周期
- }
-
- @Override
- public void onStop() {
- super.onStop();
- lifecycle.onStop();//转发生命周期
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- lifecycle.onDestroy();
- unregisterFragmentWithRoot();//转发生命周期
- }
- }
到此,可以看到 RequestManager 通过监听空白Fragment 的 lifecycle 的生命周期来管理请求的生命周期的。
Glide 初始化并且生成RequestManager,RequestManager 与 空白Fragment 的 lifecycle 生命周期绑定来管理后续的请求。
1) 空白Fragment 持有ActivityFragmentLifecycle,当空白Fragment生命周期改变的时候,调用onStart()、onStop()、onDestroy()——>
2)ActivityFragmentLifecycle 持有LifecycleListener集合,其中RequestManager是其中的一个LifecycleListener,ActivityFragmentLifecycle遍历集合,调用LifecycleListener的onStart()、onStop()、onDestroy()——>
3) RequestManager 实现了LifecycleListener, 在onStart()、onStop()、onDestroy()方法中进行请求的生命周期管理。