Glide4.11源码分析(一)生命周期的绑定

本文详细解析了Glide4.11版本的源码,从基本使用方式入手,逐步深入到Glide的初始化过程、生命周期绑定机制、线程池配置以及缓存策略等方面,帮助读者理解其高效图片加载原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Glide4.11源码分析(一)生命周期的绑定
Glide4.11源码分析(二)三级缓存之内存缓存
Glide4.11源码分析(三)子线程执行的那些事儿及本地缓存

前言

Glide库是一个优秀图片下载、展示、剪裁等功能于一体的开源库,开发中经常会用到,但是这么优秀的开源库,内部到底是什么逻辑实现的呢?今天就一起来看一看他的真面目。

基本使用

protected void onCreate(@Nullable Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.glide_activity_layout);
      imageView = ((ImageView) findViewById(R.id.img));
      RequestManager requestManager = Glide.with(this);
      RequestBuilder<Drawable> builder = requestManager.load("http://dmimg.5054399.com/allimg/pkm/pk/22.jpg");
      //拷贝一个builder,包括他的一些配置都会被拷贝进来,从而不影响原builder
//    builder = builder.autoClone();
      builder = builder.placeholder(R.mipmap.ic_launcher);
      builder = builder.error(R.mipmap.ic_launcher_round);
      builder = builder.centerCrop();
//    builder = builder.diskCacheStrategy(DiskCacheStrategy.ALL);
      builder.into(imageView);
}

这是最基本的使用方式,不过有时候我们需要扩展Glide 的API,而且可能在很多地方都会使用扩展后的Glide加载图片,那总不能没次使用的时候单独扩展吧。所以引出了另外一种使用方式

//创建类继承自AppGlideModule并用@GlideModule进行注解
@GlideModule
public class MyAppGlideModule extends AppGlideModule {
	@Override
	public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
	    super.applyOptions(context, builder);
	    //扩展修改MemoryCache
	    builder.setMemoryCache(new MySelfMemoryCache());
	    builder.setSourceExecutor(GlideExecutor.newSourceExecutor());
	    builder.setAnimationExecutor(GlideExecutor.newAnimationExecutor());
	}
	
	@Override
	public void registerComponents(@NonNull Context context, @NonNull Glide glide,
	                               @NonNull Registry registry) {
		//将默认的网络请求方式(URLConnection)改为OkHttp                               
	    registry.replace(GlideUrl.class, InputStream.class,new OKHttpUrlLoader.Factory());
	}
}
//自定义的MySelfMemoryCache和OKHttpUrlLoader类的代码不贴了,参照系统的写就行

//使用的时候可以这样使用
//GlideApp是注解为我们自动生成的
GlideApp.with(this)
       .load("http://dmimg.5054399.com/allimg/pkm/pk/22.jpg")
       .placeholder(R.mipmap.ic_launcher)
       .error(R.mipmap.ic_launcher_round)
       .fitCenter()
       .into(imageView);

看下我写的okhttpfetcher打印的log

2021-03-25 22:57:05.781 21206-21294/com.source.test D/OkHttpUrlFetcher: OkHttpUrlFetcher: 构造方法
2021-03-25 22:57:05.782 21206-21294/com.source.test D/OkHttpUrlFetcher: OkHttpUrlFetcher: 构造方法
2021-03-25 22:57:05.829 21206-21301/com.source.test D/OkHttpUrlFetcher: loadData: 我要开始loaddata了

以上就是Glide4.11的使用方式,很灵活很方便。开始逐一分析,我们以第一种使用方式的形式去分析,分析的是首次加载图片的过程。

源码分析

很明显使用的时候就是链式调用,使用了建造者模式,使用起来很方便,我们就按着调用的顺序去逐一分析每一步调用做了什么工作。先来看Glide.with(this)


> 代码片段1

  @NonNull
  public static RequestManager with(@NonNull Activity activity) {
    return getRetriever(activity).get(activity);
  }

这个方法就是通过Activity获取一个RequestManager,这个RequestManager就是负责管理和启动Glide请求的。可以通过Activity、Fragment等生命周期事件开启、停止或重启请求。至于他们怎么绑定到一起的,接着往下看,先看getRetriever(activity)方法

> 代码片段2

@NonNull 
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
  return Glide.get(context).getRequestManagerRetriever();
}

//双重检查单例模式获取Glide实例对象
public static Glide get(@NonNull Context context) {
	if (glide == null) {
		//注释1
  	GeneratedAppGlideModule annotationGeneratedModule =
      getAnnotationGeneratedGlideModules(context.getApplicationContext());
  synchronized (Glide.class) {
    if (glide == null) {
      checkAndInitializeGlide(context, annotationGeneratedModule);
    }
  }
}

注释1处是通过反射获取由编译时注解生成的GeneratedAppGlideModuleImpl。我们可以通过注解来定义GlideBuilder的全局属性,注解会生成GeneratedAppGlideModuleImpl,而注释1就是通过反射获取GeneratedAppGlideModuleImpl实例,进而拿到我们设置的全局属性。之后就调用checkAndInitializeGlide,最终来到了initializeGlide()方法

> 代码片段3

private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder,@Nullable GeneratedAppGlideModule annotationGeneratedModule) {
      
   //.....略......省略处的逻辑是通过解析Manifest.xml文件,获取GlideModule,这种方式已经不鼓励使用了
   
   //注释2 
    RequestManagerRetriever.RequestManagerFactory factory =
        annotationGeneratedModule != null
            ? annotationGeneratedModule.getRequestManagerFactory()
            : null;
    builder.setRequestManagerFactory(factory);
    
   //....略....
   
    if (annotationGeneratedModule != null) {
    	//这里的builder是通过new GlideBuilder生成的,这里就调用到我们写的注解的地方了,会给GlideBuilder对象设置一些线程池,内存缓存方式等内容
      annotationGeneratedModule.applyOptions(applicationContext, builder);
    }
    //注释3
    Glide glide = builder.build(applicationContext);
    
   	//...略...
   	
    if (annotationGeneratedModule != null) {
    //用于注册一些组件,这些组件包括 解码流、解析exif的方向的组件
      annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
    }
    //Glide 类实现了ComponentCallbacks2接口,在此注册回调接口 这个接口回调用于内存管理的
    applicationContext.registerComponentCallbacks(glide);
    Glide.glide = glide;
  }

注释2 的意思如果使用了注解,则会通过注解生成的annotationGeneratedModulegetRequestManagerFactory()获取RequestManagerFactory ,而注解生成的类GeneratedAppGlideModuleImplgetRequestManagerFactory中直接new GeneratedRequestManagerFactory(),这个factory会在build方法中生成一个GlideRequests对象。这对象继承了RequestManager。如果没有使用注解,那factory就是null。
下面先看注释3出的方法调用

> 代码片段4
com.bumptech.glide.GlideBuilder.java

Glide build(@NonNull Context context) {
    if (sourceExecutor == null) {
      sourceExecutor = GlideExecutor.newSourceExecutor();
    }

    if (diskCacheExecutor == null) {
      diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
    }

    if (animationExecutor == null) {
      animationExecutor = GlideExecutor.newAnimationExecutor();
    }

    if (memorySizeCalculator == null) {
      memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
    }

    if (connectivityMonitorFactory == null) {
      connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
    }

    if (bitmapPool == null) {
      int size = memorySizeCalculator.getBitmapPoolSize();
      if (size > 0) {
        bitmapPool = new LruBitmapPool(size);
      } else {
        bitmapPool = new BitmapPoolAdapter();
      }
    }

    if (arrayPool == null) {
      arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
    }

    if (memoryCache == null) {
      memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
    }

    if (diskCacheFactory == null) {
      diskCacheFactory = new InternalCacheDiskCacheFactory(context);
    }

    if (engine == null) {
    //这里创建Engine对象,这里创建的Engined对象中有个成员变量engineJobFactory是EngineJobFactory类型的,后面用的到
      engine =
          new Engine(
              memoryCache,
              diskCacheFactory,
              diskCacheExecutor,
              sourceExecutor,
              GlideExecutor.newUnlimitedSourceExecutor(),
              animationExecutor,
              isActiveResourceRetentionAllowed);
    }

    if (defaultRequestListeners == null) {
      defaultRequestListeners = Collections.emptyList();
    } else {
      defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
    }
	//这里创建RequestManagerRetriever,参数requestManagerFactory就是代码片段3注释2中
	//通过调用builder.setRequestManagerFactory(factory)传进来的;
	//这个factory要么是null要么就是GeneratedRequestManagerFactory对象。
	//RequestManagerRetriever的构造方法中判断factory如果为null,
	//就会为factory赋一个默认对象,详情见下面的方法
    RequestManagerRetriever requestManagerRetriever =
        new RequestManagerRetriever(requestManagerFactory);

    return new Glide(
        context,
        engine,
        memoryCache,
        bitmapPool,
        arrayPool,
        requestManagerRetriever,
        connectivityMonitorFactory,
        logLevel,
        defaultRequestOptionsFactory,
        defaultTransitionOptions,
        defaultRequestListeners,
        isLoggingRequestOriginsEnabled,
        isImageDecoderEnabledForBitmaps);
  }

public RequestManagerRetriever(@Nullable RequestManagerFactory factory) {
  this.factory = factory != null ? factory : DEFAULT_FACTORY;
  handler = new Handler(Looper.getMainLooper(), this /* Callback */);
}

看下new RequestManagerRetriever这句代码中判断factory是null的话就会使用DEFAULT_FACTORY对象,这是默认的factory ,他的build方法直接new了一个RequestManager
上面设置了一系列的成员变量,最终new了一个Glide出来。下面以表格形式说明这些成员变量的用途。

说明:GlideExecutor就是线程池的代理类,内部通过建造者模式创建不同类型的ThreadPoolExecutor的代理类,来实现线程池的功能。

对象所属类型说明用途
sourceExecutorGlideExecutor此线程池的核心线程数和最大线程数相等,值为4或者设备的内核数执行网络请求的线程池。
diskCacheExecutorGlideExecutor不可以进行网络请求。此线程池的核心线程数和最大线程数均为1执行硬盘缓存线程池
animationExecutorGlideExecutor不允许网络请求。此线程池的核心线程数和最大线程数相等,当sourceExecutor线程数大于4的时候,此线程池线程数为2,否则就是1执行动画的线程池
memorySizeCalculatorMemorySizeCalculator缓存计算器。根据设备的像素密度和屏幕宽高等信息计算并设置缓存大小
connectivityMonitorFactoryDefaultConnectivityMonitorFactoryConnectivityMonitor的工厂类,ConnectivityMonitor类是用来管理网络连接断开情况,而DefaultConnectivityMonitorFactory类根据APP是否有permission.ACCESS_NETWORK_STATE权限来分别创建DefaultConnectivityMonitor和NullConnectivityMonitor 类
bitmapPoolBitmapPool根据bitmapPoolSize大小,使用不同缓存技术。而bitmapPoolSize又是MemorySizeCalculator根据屏幕像素位数及设备APP的分配的内存大小决定的。1、如果bitmapPoolSize大于0 ,缓存池就是LruBitmapPool,而LruBitmapPool缓存策略分两种,a)、设备SDK版本大于19,使用SizeConfigStrategy缓存策略类:即缓存key是通过图片的config(通过bitma.getConfig方法获取)和图片的byte大小(通过Bitmap.getAllocationByteCount方法获取)生成的;b)、设备SDK版本小于19,使用AttributeStrategy缓存策略类:即缓存key是通过图片的宽、高和config生成的。2、如果bitmapPoolSize不大于0,缓存池就是BitmapPoolAdapter,这个其实就不是缓存池,因为他的get方法就是创建一个图片,而put方法就是回收图片用做Bitmap对象的复用
arrayPoolLruArrayPool数组池,缓存用,池大小是固定的,回收策略采用的是Lru缓存策略
memoryCacheLruResourceCache内存缓存池,采用LRU缓存策略缓存已经完成解析的资源
diskCacheFactoryInternalCacheDiskCacheFactory磁盘缓存工厂类,磁盘缓存采用了文件快照存储的方式,会生成一个名字journal的日志文件,保存了缓存的相关信息。每条缓存的键是都是固定数量的字符串,值就是字节序列,能够直接读取流或者作为文件系统访问创建DiskLruCache
engineEngine真正负责加载资源并管理活动的或缓存资源的引擎类
defaultRequestListenersRequestListenerRequestListener集合
requestManagerRetrieverRequestManagerRetriever此类实现了Handler.Callback接口,内部有大都是静态方法获取或者创建RequestManager的类

以上表格中展示的就是此方法中设置的成员变量的类型及相关说明,这些变量都会用来作为接下来要new的 Glide的参数,后续加载、缓存图片的时候会用到。

Glide的构造方法有一百多行代码,Glide构造方法主要做的工作就是设置成员变量,创建了一个注册表Registry(相当于glide的大管家,管理Glide加载图片的方式,编解码等功能)和GlideContext对象(它是Glide中所有加载的全局上下文,其中包含并公开了加载资源所需的各种注册表和类)。

到此只是分析了代码片段2中第一个方法里的代码return Glide.get(context).getRequestManagerRetriever();中的前半部分,Glide对象已经生成了,所以这句代码的后半部分调用了Glide类的getRequestManagerRetriever方法获取到RequestManagerRetriever对象。接着回到代码片段1中看return getRetriever(activity).get(activity);这句代码的后半部分,也就是RequestManagerRetriever类的get(Activity activity)方法。

> 代码片段5

@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));
  }
}

这里会区分是否是在后台线程和主线程,如果Glide是在后台线程使用,则传递的是ApplicationContext,否则传的的是Activity对象。先看下第一种情况,这种情况会最终调用下面代码

> 代码片段6
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) {
		//强制使用ApplicationLifecycle来接管RequestManager的生命周期
          // TODO(b/27524013): Factor out this Glide.get() call.
          Glide glide = Glide.get(context.getApplicationContext());
          applicationManager =
              factory.build(
                  glide,
                  new ApplicationLifecycle(),
                  new EmptyRequestManagerTreeNode(),
                  context.getApplicationContext());
        }
      }
    }
    return applicationManager;
  }

如果使用注解的话,factory就是注解自动生成的,是由注解自动创建GeneratedRequestManagerFactory的对象,否则factory就是默认的RequestManagerFactory对象,然后factory调用build方法,将ApplicationLifecycle、getApplicationContext等作为参数调用RequestManager的构造方法。接下来看代码片段5的第二种情况,在主线程使用Glide加载图片。

> 代码片段7

@NonNull
private RequestManager fragmentGet(@NonNull Context context,@NonNull android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,boolean isParentVisible) {
  //注释4
  RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
  RequestManager requestManager = current.getRequestManager();
  if (requestManager == null) {
    Glide glide = Glide.get(context);
    //注释4.1
    requestManager =
        factory.build(
            glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
    current.setRequestManager(requestManager);
  }
  return requestManager;
}

@NonNull
private RequestManagerFragment getRequestManagerFragment(
     @NonNull final android.app.FragmentManager fm,
     @Nullable android.app.Fragment parentHint,
     boolean isParentVisible) {
   RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
   if (current == null) {
     current = pendingRequestManagerFragments.get(fm);
     if (current == null) {
       current = new RequestManagerFragment();
       current.setParentFragmentHint(parentHint);
       if (isParentVisible) {
         current.getGlideLifecycle().onStart();
       }
       pendingRequestManagerFragments.put(fm, current);
       fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
       handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
     }
   }
   return current;
 }

我们来看下是如何将Fragment的生命周期和请求绑定的。方法fragmentGet很好理解,注释4出现调用getRequestManagerFragment,获取一个RequestManagerFragment,那就先看看RequestManagerFragment方法是怎么取的,getRequestManagerFragment方法中先用FragmentManager通过Tag FRAGMENT_TAG来找Fragment,如果找不到就通过pendingRequestManagerFragments缓存去找,如果还找不到就new一个然后存储下来并返回。RequestManagerFragment的构造方法中会创建ActivityFragmentLifecycle对象并赋值给成员变量lifecycle,可参考下面代码片段8。返回之后接着看fragmentGet后续工作,看注释4.1处,会生成requestManager对象,并将RequestManagerFragment中的lifecycle作为参数传进build方法中,并且将requestManager对象设置给RequestManagerFragment
那么RequestManagerFragment是个什么东西?其实这里是用Fragment的生命周期来绑定请求的生命周期的

> 代码片段8
//RequestManagerFragment就是一个没有view的空Fragment,它持有RequestManager对象引用,和ActivityFragmentLifecycle对象引用
public class RequestManagerFragment extends Fragment {

  private final ActivityFragmentLifecycle lifecycle;
  @Nullable private RequestManager requestManager;

  public RequestManagerFragment() {
    this(new ActivityFragmentLifecycle());
  }

  @VisibleForTesting
  @SuppressLint("ValidFragment")
  RequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
    this.lifecycle = lifecycle;
  }
  @Override
  public void onStart() {
    super.onStart();
    lifecycle.onStart();
  }
//生命周期回调,同时调用成员变量lifecycle的生命周期
  @Override
  public void onStop() {
    super.onStop();
    lifecycle.onStop();
  }
  //...略...
}

class ActivityFragmentLifecycle implements Lifecycle {
  private final Set<LifecycleListener> lifecycleListeners =
      Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
  private boolean isStarted;
  private boolean isDestroyed;
  @Override
  public void addListener(@NonNull LifecycleListener listener) {
    lifecycleListeners.add(listener);

    if (isDestroyed) {
      listener.onDestroy();
    } else if (isStarted) {
      listener.onStart();
    } else {
      listener.onStop();
    }
  }
void onStart() {
  isStarted = true;
  for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
    lifecycleListener.onStart();
  }
}

void onStop() {
  isStarted = false;
  for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
    lifecycleListener.onStop();
  }
}
//略。。。
}

上面代码第二段是ActivityFragmentLifecycle。RequestManagerFragment生命周期调用的时候就会调用ActivityFragmentLifecycle的onStart、onStop等方法,这些方法中会遍历集合lifecycleListeners,并调用集合里监听对象响应的方法。集合中的这些对象是通过调用ActivityFragmentLifecycle对象的addListener方法加进去的。这里先标记一下。待会就能看到这个addListener是什么时候加入的。
现在返回代码代码片段7中的注释4.1,这里的factory的来历已经在代码片段3注释2代码片段4中解释了。调用factory的build方法,这里我们看默认factoryDEFAULT_FACTORY中的build方法,该方法直接new了一个RequestManager对象,看下构造方法

>代码片段8.1

RequestManager(
      Glide glide,
      Lifecycle lifecycle,
      RequestManagerTreeNode treeNode,
      RequestTracker requestTracker,
      ConnectivityMonitorFactory factory,
      Context context) {
    this.glide = glide;
    this.lifecycle = lifecycle;

    connectivityMonitor =
        factory.build(
            context.getApplicationContext(),
            new RequestManagerConnectivityListener(requestTracker));

    if (Util.isOnBackgroundThread()) {
      mainHandler.post(addSelfToLifecycle);
    } else {
    	//注释4.2
      lifecycle.addListener(this);
    }
    lifecycle.addListener(connectivityMonitor);

    defaultRequestListeners =
        new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
    setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());

    glide.registerRequestManager(this);
  }

构造方法的第二个参数lifecycle就前面获取的RequestManagerFragment对象的成员变量lifecycle也就是ActivityFragmentLifecycle类型的对象,看上面代码中注释4.2调用了lifecycle.addListener(this),结合上文中加粗的标记的地方,也就是这里先标记一下那个文字的地方,由于RequestManager实现了LifecycleListener,所以此时RequestManagerFragment的生命周期方法已经和RequestManager生命周期方法绑定了。

结论:RequestManagerFragment的生命周期方法onStart、onStop、onDestory调用的时候,RequestManager的相对应的生命周期方法也将得到回调。
先看下RequestManager的onStart、onStop方法干了啥

@Override
public synchronized void onStart() {
  resumeRequests();
  targetTracker.onStart();
}

/**
 * Lifecycle callback that unregisters for connectivity events (if the
 * android.permission.ACCESS_NETWORK_STATE permission is present) and pauses in progress loads.
 */
@Override
public synchronized void onStop() {
  pauseRequests();
  targetTracker.onStop();
}

看上去好像是加载了请求。这部分下篇文章再讲。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值