Glide v4 源码浅析(1)-with


简述

Glide为Android平台下的图片加载框架,它的使用方法可以查看教程文档

这里从一个最简单的使用实例入手,分析glide源码调用过程(使用的glide版本为v4.8.0):

Glide.with(activity)
     .load(imgUrl)
     .into(imageView);

本例实现了在一个FragmentActivity中,加载远程图片,显示在imageview视图上。图片加载过程大致可以分为三步:

  • with: 预备开启一个加载,并与当前Activity生命周期绑定;
  • load:设置数据源,构建请求的参数;
  • into:创建请求,开始真正的加载图片,最终显示在视图上。

接下来从第一步with方法开始,看看源码中做了什么操作。

源码分析

with方法中主要做了两件事,一是初始化Glide对象,二是返回合适的RequestManager对象。

Glide初始化

在Glide类中,有多个with方法的重载实现,最终都是返回RequestManager对象,(RequestManager负责管理发起的加载Request),如图:

简单概括它们的作用是当传入的上下文为FragmentActivity或者可以取到FragmentActivity时,可以将本次加载与FragmentActivity的生命周期进行绑定,其中又分别适配了v4和app的FragmentManager。

在本例中将会调用下面的重载方法:

@NonNull
publicstatic RequestManager with(@NonNull FragmentActivity activity) {
  return getRetriever(activity).get(activity);
}

其中getRetriever方法返回RequestManagerRetriever(顾名思义,它负责创建或检索出合适的RequestManager)。

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

看Glide.get(context)方法,返回单例:

@NonNull
public static Glide get(@NonNull Context context) {
  if (glide == null) {
    synchronized (Glide.class) {
      if (glide == null) {
        checkAndInitializeGlide(context);
      }
    }
  }

  return glide;
}

checkAndInitializeGlide方法中加了一个boolean变量判断避免重复调用初始化,其中又调用initializeGlide方法。

接下来就是Glide的初始化过程

private static void initializeGlide(@NonNull Context context) {
  initializeGlide(context, new GlideBuilder());
}

@SuppressWarnings("deprecation")
privatestatic void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
  Context applicationContext = context.getApplicationContext();
  // 获取注解生成的自定义的GlideModule,具体使用查看Glide文档「Generated API」说明。
  GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();
  List<com.bumptech.glide.module.GlideModule> manifestModules = Collections.emptyList();
  if (annotationGeneratedModule == null || annotationGeneratedModule.isManifestParsingEnabled()) {
    // 获取在AndroidManifest中注册的GlideModule(Glide V4之前的版本使用)。
    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()) {
      // 排除不需要的GlideModule(由自己决定)。
      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());
    }
  }

  // 获取自定义的RequestManagerFactory,设置给GlideBuilder。
  RequestManagerRetriever.RequestManagerFactory factory =
      annotationGeneratedModule != null
          ? annotationGeneratedModule.getRequestManagerFactory() : null;
  builder.setRequestManagerFactory(factory);
  for (com.bumptech.glide.module.GlideModule module : manifestModules) {
    // 可以在自定义的GlideModule中给GlideBuilder设置配置。
    module.applyOptions(applicationContext, builder);
  }
  if (annotationGeneratedModule != null) {
    // 可以在自定义的GlideModule中给GlideBuilder设置配置。
    annotationGeneratedModule.applyOptions(applicationContext, builder);
  }
  // 通过GlideBuilder构造了一个Glide对象。
  Glide glide = builder.build(applicationContext);
  for (com.bumptech.glide.module.GlideModule module : manifestModules) {
    // 可以在自定义的GlideModule中给glide中的Registry添加或替换组件。
    module.registerComponents(applicationContext, glide, glide.registry);
  }
  if (annotationGeneratedModule != null) {
    // 可以在自定义的GlideModule中给glide中的Registry添加或替换组件。
    annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
  }
  // 注册ComponentCallbacks2用以监听内存使用情况。
  applicationContext.registerComponentCallbacks(glide);
  Glide.glide = glide;
}

在本例中使用默认的glide配置,没有自定义GlideModule,直接看builder.build(applicationContext)方法:

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

  // 初始化生成网络监听广播注册的工厂类,该Factory会根据是否有NETWORK_PERMISSION生成对应的监听器(通常情况下都应该申请)。拥有权限情况下的监听器会注册广播监听CONNECTIVITY_ACTION,当收到联网广播时会触发RequestManager尝试重试请求。
  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());
  }

  // 初始化Resource缓存容器
  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);
  }

  // 初始化获取RequestManager的工具类,接下来马上就会用到。
  RequestManagerRetriever requestManagerRetriever =
      new RequestManagerRetriever(requestManagerFactory);

  // 最终创建并返回Glide对象
  return new Glide(
      context,
      engine,
      memoryCache,
      bitmapPool,
      arrayPool,
      requestManagerRetriever,
      connectivityMonitorFactory,
      logLevel,
      defaultRequestOptions.lock(),
      defaultTransitionOptions);
}

GlideBuilder的build方法中初始化了多个线程池对应不同使用功能,便于不同模块的线程管理,以及缓存容器和Engine、RequestManagerRetriever对象。之后实例化Glide对象并传入各个参数。

接着看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) {
 this.engine = engine;
 this.bitmapPool = bitmapPool;
 this.arrayPool = arrayPool;
 this.memoryCache = memoryCache;
 this.requestManagerRetriever = requestManagerRetriever;
 this.connectivityMonitorFactory = connectivityMonitorFactory;

 DecodeFormat decodeFormat = defaultRequestOptions.getOptions().get(Downsampler.DECODE_FORMAT);
 bitmapPreFiller = new BitmapPreFiller(memoryCache, bitmapPool, decodeFormat);
 
 final Resources resources = context.getResources();   
 
 registry = new Registry();
 // Right now we're only using this parser for HEIF images, which are only supported on OMR1+.
 // If we need this for other file types, we should consider removing this restriction.
 // Note that order here matters. We want to check the ExifInterface parser first for orientation
 // and then fall back to DefaultImageHeaderParser for other fields.
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
   registry.register(new ExifInterfaceImageHeaderParser());
 }
 registry.register(new DefaultImageHeaderParser());
 
 ···
 
 registry
     .append(ByteBuffer.class, new ByteBufferEncoder())
     ···
     .append(Registry.BUCKET_BITMAP, ByteBuffer.class, Bitmap.class, byteBufferBitmapDecoder)
     ···
     .append(Bitmap.class, Bitmap.class, UnitModelLoader.Factory.<Bitmap>getInstance())
     .append(
         Registry.BUCKET_BITMAP, Bitmap.class, Bitmap.class, new UnitBitmapDecoder())
     .append(Bitmap.class, bitmapEncoder)
     ···
     .register(new ByteBufferRewinder.Factory())
     ···
     .register(
         Bitmap.class,
         BitmapDrawable.class,
         new BitmapDrawableTranscoder(resources))
     ···
     ;

 ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
 glideContext =
     new GlideContext(
         context,
         arrayPool,
         registry,
         imageViewTargetFactory,
         defaultRequestOptions,
         defaultTransitionOptions,
         engine,
         logLevel);
}

这里主要做了三件事:
1.保存在GlideBuilder中完成初始化的对象;
2.初始化Registry对象,该对象中注册了一系列资源转换和编解码的工具类,后续流程会从中查找对应的工具类去解析和处理资源;
3.初始化GlideContext对象,该对象继承自ContextWrapper,后续的流程中会通过它获取注册表和引擎等加载资源所需的对象。

以上完成了Glide对象的创建和初始化。回到Glide的getRetriever方法中,这里将返回RequestManagerRetriever对象,接下来是通过它获取RequestManager对象。

RequestManager获取

RequestManagerRetriever类的get方法也有多个重载:

with方法需要多个重载主要是因为这里,这里根据参数类型查找FragmentManager,利用它实现和当前activity的生命周期绑定。

先看get(Context):

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

  return getApplicationManager(context);
}

根据context的类型再调用相应的get方法。若当前非主线程或上下文是Application,直接调用getApplicationManager方法(这种情况下不会绑定生命周期)。

不进行生命周期绑定的RequestManager

当在子线程调用with方法,或传入上下文为application时,会通过getApplicationManager方法返回RequestManager对象:

@NonNull
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) {
        // Normally pause/resume is taken care of by the fragment we add to the fragment or
        // activity. However, in this case since the manager attached to the application will not
        // receive lifecycle events, we must force the manager to start resumed using
        // ApplicationLifecycle.

        // TODO(b/27524013): Factor out this Glide.get() call.
        Glide glide = Glide.get(context.getApplicationContext());
        applicationManager =
            factory.build(
                glide,
                // ApplicationLifecycle实现Lifecycle接口,用于跟踪和通知Application的生命周期事件。
                new ApplicationLifecycle(),
                new EmptyRequestManagerTreeNode(),
                context.getApplicationContext());
      }
    }
  }

  return applicationManager;
}

该方法会返回一个单例的RequestManager对象,通过工厂模式创建,factory在RequestManagerRetriever实例化时候赋值,默认为DEFAULT_FACTORY:

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) {
    return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
  }
};

可以看到build方法直接new了一个RequestManager对象,接着看看RequestManager的构造方法:

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;
  // requestTracker用于跟踪、取消和重新启动进行中、已完成和失败的请求。
  this.requestTracker = requestTracker;
  this.context = context;
  
  // 创建网络连接监听器,当网络恢复可用时会通过requestTracker尝试重启请求。
  connectivityMonitor =
      factory.build(
          context.getApplicationContext(),
          new RequestManagerConnectivityListener(requestTracker));

  // If we're the application level request manager, we may be created on a background thread.
  // In that case we cannot risk synchronously pausing or resuming requests, so we hack around the
  // issue by delaying adding ourselves as a lifecycle listener by posting to the main thread.
  // This should be entirely safe.
  // 在主线程添加LifecycleListener到Lifecycle中
  if (Util.isOnBackgroundThread()) {
    mainHandler.post(addSelfToLifecycle);
  } else {
    lifecycle.addListener(this);
  }
  lifecycle.addListener(connectivityMonitor);
  
  setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());

  // 将自身保存到glide的managers成员变量中(managers为一个ArrayList)。
  glide.registerRequestManager(this);
}

这里的lifecycle为ApplicationLifecycle,它的addListener方法只是通知新的监听器已启动。

与当前Activity进行生命周期绑定的RequestManager

get的其他重载方法都是试图获取到FragmentManager,然后调用supportFragmentGet方法或者fragmentGet方法查找或创建RequestManager对象。
(ps:fragmentGet方法适配android.app.FragmentManager,已弃用)

这里以get(FragmentActivity)为例:

@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
  if (Util.isOnBackgroundThread()) {
    return get(activity.getApplicationContext());
  } else {
    assertNotDestroyed(activity);
    // 获取FragmentManager
    FragmentManager fm = activity.getSupportFragmentManager();
    return supportFragmentGet(
        activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
  }
}

关键在supportFragmentGet方法:

@NonNull
private RequestManager supportFragmentGet(
    @NonNull Context context,
    @NonNull FragmentManager fm,
    @Nullable Fragment parentHint,
    boolean isParentVisible) {
  // 查找SupportRequestManagerFragment对象,它就是一个Fragment
  SupportRequestManagerFragment current =
      getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
  // 从SupportRequestManagerFragment中获取requestManager  
  RequestManager requestManager = current.getRequestManager();
  // 若不存在则创建,之后保存在SupportRequestManagerFragment中
  if (requestManager == null) {
    // TODO(b/27524013): Factor out this Glide.get() call.
    Glide glide = Glide.get(context);
    // 这里创建RequestManager时传入了ActivityFragmentLifecycle
    requestManager =
        factory.build(
            glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
    current.setRequestManager(requestManager);
  }
  return requestManager;
}

该方法中会通过getSupportRequestManagerFragment方法获取一个Fragment,返回其中的RequestManager,若不存在则新建一个,并保存在Fragment中。

接着看getSupportRequestManagerFragment方法:

@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
    @NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
  // 通过tag查找当前页面中的指定Fragment
  SupportRequestManagerFragment current =
      (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
  if (current == null) {
    // 获取已创建但等待往当前页面添加的Fragment,避免fm add fragment期间重复创建
    current = pendingSupportRequestManagerFragments.get(fm);
    if (current == null) {
      // 初始化SupportRequestManagerFragment
      current = new SupportRequestManagerFragment();
      current.setParentFragmentHint(parentHint);
      if (isParentVisible) {
        current.getGlideLifecycle().onStart();
      }
      // 保存到集合中避免重复创建
      pendingSupportRequestManagerFragments.put(fm, current);
      // 将SupportRequestManagerFragment添加到当前页面中
      fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
      // 在handler的handleMessage中会将上面保存的从集合中移除
      handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
    }
  }
  return current;
}

这里可以看出,Glide是通过往当前页面添加一个Fragment,借助Fragment的生命周期来通知RequestManager,来实现绑定管理。

SupportRequestManagerFragment和RequestManager之间是通过ActivityFragmentLifecycle来实现生命周期回调:

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

@VisibleForTesting
@SuppressLint("ValidFragment")
public SupportRequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
  this.lifecycle = lifecycle;
}

在supportFragmentGet方法中创建RequestManager时,会传入SupportRequestManagerFragment的lifecycle成员变量:

requestManager =
    factory.build(
        glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
current.setRequestManager(requestManager);

而在RequestManager的构造方法中,又会向这个lifecycle中注册LifecycleListener接口的实现类即RequestManager自身:

if (Util.isOnBackgroundThread()) {
  // 发送到主线程添加
  mainHandler.post(addSelfToLifecycle);
} else {
  // 添加自身,RequestManager实现了LifecycleListener接口
  lifecycle.addListener(this);
}
// 添加网络监听器
lifecycle.addListener(connectivityMonitor);

因此实现了绑定关系:

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

在Fragment的生命周期回调方法中调用lifecycle的对应方法,而lifecycle中又会调用LifecycleListener接口的相应方法,即RequestManager的onStart、onStop、onDestroy方法。

总结

Glide的with方法会初始化Glide单例对象,并完成一系列默认和自定义配置。之后通过它的requestManagerRetriever成员变量查找创建返回RequestManager对象,后续会通过这个RequestManager进行资源请求的管理。在获取RequestManager的过程中,会通过往当前页面添加一个Fragment,来实现RequestManager和页面生命周期绑定。

后续流程分析见《Glide v4 源码浅析(2)-load方法与Registry说明》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值