Glide源码分析之Glide和RequestManager构建过程

Glide源码分析之Glide和RequestManager构建过程
Glide源码分析之自定义模块及Glide如何触发网络请求(未发布)
Glide源码分析之load(url)和into(iv)(未发布)
Glide源码分析之缓存机制(未发布)

基本用法

多数情况下,使用Glide加载图片非常简单,一行代码足矣:

Glide.with(fragment).load(myUrl).into(imageView)

取消加载:

Glide.with(fragment).clear(imageView);

实际上,Glide.with() 中传入的 Activity 或 Fragment 实例销毁时,Glide 会自动观察 Activity 或 Fragment 的生命周期取消加载并回收资源,实际上Glide为了监听Activity 或 Fragment的声明周期会在内部添加一个fragment就是为监听生命周期。

看一下Glide.with()的源码:

 /**
 * with方法主要的逻辑:
 * 1、在1步骤中通过getRetriever获取到在初始化Glide时创建的RequestManagerRetriever实例;
 * 2、在2步骤中通过RequestManagerRetriever的get方法获取RequestManager实例。
 *
 * 

* RequestManagerRetriever用于创建新的RequestManagers或从activity和fragment中检索现有的RequestManagers * * @param context * @return */ @NonNull public static RequestManager with(@NonNull Context context) { // 调用getRetriever获取RequestManagerRetriever RequestManagerRetriever requestManagerRetriever = getRetriever(context);// 1 // 调用RequestManagerRetriever的get方法,获取RequestManager(图片请求加载管理者) RequestManager requestManager = requestManagerRetriever.get(context); // 2 return requestManager; } /** * 请求资源使用Activityh生命周期同步 * * @param activity * @return */ @NonNull public static RequestManager with(@NonNull Activity activity) { return getRetriever(activity).get(activity); } /** * 请求资源使用FragmentActivity生命周期同步 */ @NonNull public static RequestManager with(@NonNull FragmentActivity activity) { return getRetriever(activity).get(activity); } /** * 请求资源使用Fragment生命周期同步 */ @NonNull public static RequestManager with(@NonNull Fragment fragment) { return getRetriever(fragment.getActivity()).get(fragment); } /** * 请求资源使用android.app.Fragment生命周期同步 */ @SuppressWarnings("deprecation") @Deprecated @NonNull public static RequestManager with(@NonNull android.app.Fragment fragment) { return getRetriever(fragment.getActivity()).get(fragment); } /** * 通过View去搜索其依附的Activity或者Fragment并使用它们作为请求资源使用生命周期同步 */ @NonNull public static RequestManager with(@NonNull View view) { return getRetriever(view.getContext()).get(view); }

可以看到Glide.with(context)有几个重载的方法,Glide.with(context)方法主要的逻辑:
1、在1步骤中通过getRetriever获取到在初始化Glide时创建的RequestManagerRetriever实例;
2、在2步骤中通过RequestManagerRetriever的get方法获取RequestManager实例。 RequestManagerRetriever用于创建新的RequestManagers或从activity和fragment中检索现有的RequestManagers

Glide.with(context)最终调用getRetriever(context),然后再调用RequestManagerRetriever的实例get()方法,去获取RequestManager对象:

  /**
 * getRetriever方法主要逻辑:
 * 1、在1步骤,会创建Glide实例并且初始化Glide实例,还会创建RequestManagerRetriever实例对象;
 * 2、在2步骤直接返回RequestManagerRetriever实例
 *
 * @param context
 * @return
 */
@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context) { // 1.2
    // Glide.get(context) 获取Glide对象,包括初始化之类的配置
    Glide glide = Glide.get(context);//1
    // 通过Glide获取RequestManagerRetriever
    // 可能你会惊讶在哪 初始化RequestManagerRetriever的,其实是在GlideBuilder的build方法中
    RequestManagerRetriever requestManagerRetriever = glide.getRequestManagerRetriever();// 2
    return requestManagerRetriever;
}

1、 Glide.get(context) 获取Glide对象包括初始化之类的配置,初始化后面会讲GlideBiulder;
2、通过Glide对象获取RequestManagerRetriever, 可能你会惊讶在哪 初始化RequestManagerRetriever的,其实是在GlideBuilder的build方法中。

接下来看一下调用RequestManagerRetriever 的get方法,也是有几个重载;

 /**
 * 

* 上面getRetriever(context)方法,主要是构建Glide和RequestManagerRetriever *

* RequestManagerRetriever:一组静态方法,用于创建新的RequestManagers或从活动和片段中检索现有的RequestManagers。 *

* 这一步就是构建RequestManager:描述图片加载请求管理者 *

*

* 作用:主要是通过传入的context构建RequestManager实例,当然你这里可会从activity和fragment中获取已经存在的RequestManager * 为什么需要context?主要是构建的RequestManager即请求管理,需要感知各组件的生命周期,例如:application、activity和fragment *

* 主要的逻辑: * 1、在1步骤中判断是否是在主线程和是不是Application,如果我们是在非主线程当中使用的Glide,那么不管你是传入的Activity还是Fragment,都会被强制当成Application来处理 * 2、在2步骤中直接当成Application处理; * 3、最后会通过RequestManager工厂(RequestManagerFactory)创建RequestManager实例 *

* 最后: * 虽然get方法有多个重载其实逻辑的处理只有两种: * 1、传入的context是非Application参数的情况: * 不管是传入的context是Activity、FragmentActivity、v4包下的Fragment、还是app包下的Fragment, * 最终的逻辑是一样的,会向当前的Activity当中添加一个隐藏的Fragment。因为Glide需要感知加载的生命周期 * 2、传入的context是Application参数的情况,或者是在后台线程: * 如果传入的context是Application或者是在后台线程,直接就调用getApplicationManager()方法来获取一个RequestManager对象 *

*

* *

* 注意这里的get方法都是单例的 * * @param context * @return */ @NonNull public RequestManager get(@NonNull Context context) { if (context == null) { throw new IllegalArgumentException("You cannot start a load on a null Context"); //如果我们是在非主线程当中使用的Glide,那么不管你是传入的Activity还是Fragment,都会被强制当成Application来处理 } else if (Util.isOnMainThread() && !(context instanceof Application)) {//1 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);// 2 } @NonNull public RequestManager get(@NonNull FragmentActivity activity) { if (Util.isOnBackgroundThread()) { return get(activity.getApplicationContext()); } else { assertNotDestroyed(activity); // 获取当前activity的FragmentManager,因为你需要为当前activity添加隐藏的fragment FragmentManager fm = activity.getSupportFragmentManager(); return supportFragmentGet(activity, fm, null, isActivityVisible(activity)); } } @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()); } } @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)); } } @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()); } // Support Fragments. // Although the user might have non-support Fragments attached to FragmentActivity, searching // for non-support Fragments is so expensive pre O and that should be rare enough that we // prefer to just fall back to the Activity directly. 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); }

1、上面getRetriever(context)方法,主要是构建Glide和RequestManagerRetriever
2、RequestManagerRetriever:一组静态方法,用于创建新的RequestManagers或从活动和片段中检索现有的RequestManagers。
3、这一步就是构建RequestManager:描述图片加载请求管理者
4、 作用:主要是通过传入的context构建RequestManager实例,当然你这里可会从activity和fragment中获取已经存在的RequestManager
5、为什么需要context?主要是构建的RequestManager即请求管理,需要感知各组件的生命周期,例如:application、activity和fragment
6、主要的逻辑:

  • 在1步骤中判断是否是在主线程和是不是Application,如果我们是在非主线程当中使用的Glide,那么不管你是传入的Activity还是Fragment,都会被强制当成Application来处理
    • 在2步骤中直接当成Application处理;
    • 最后会通过RequestManager工厂(RequestManagerFactory)创建RequestManager实例
      最后:虽然get方法有多个重载其实逻辑的处理只有两种:传入的context是非Application参数的情况:不管是传入的context是Activity、FragmentActivity、v4包下的Fragment、还是app包下的Fragment,最终的逻辑是一样的,会向当前的Activity当中添加一个隐藏的Fragment。因为Glide需要感知加载的生命周期,
      传入的context是Application参数的情况,或者是在后台线程:
      如果传入的context是Application或者是在后台线程,直接就调用getApplicationManager()方法来获取一个RequestManager对象
      注意这里的get方法都是单例的

可以看到在get方法中通过supportFragmentGet方法和getSupportRequestManagerFragment构建隐藏的fragment:

 /**
 * 主要逻辑:
 * 1、搜索是否已经添加了隐藏的Fragment到当前的Activity中,如果已经添加过了是由缓存的。
 * 2、如果在当前activity,已经添加了隐藏的Fragment,就尝试从隐藏的Fragment中搜索RequestManager,
 * 如果没有找到,就调用RequestManager工厂创建一个RequestManager,并添加到隐藏的Fragment中,然后返回RequestManager实例。
 * 

* 注意:其实一个Activity就存在一个RequestManager,它们的关系是activity-SupportRequestManagerFragment-RequestManager一一对应 * * @param context * @param fm * @param parentHint * @param isParentVisible * @return */ @NonNull private RequestManager supportFragmentGet(@NonNull Context context, @NonNull FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) { // 搜索隐藏的Fragment SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint, isParentVisible); //从隐藏的Fragment搜索RequestManager RequestManager requestManager = current.getRequestManager(); // 如果不存在就直接创建RequestManager并添加到隐藏的Fragment中缓存 if (requestManager == null) { Glide glide = Glide.get(context); requestManager = factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context); current.setRequestManager(requestManager); } return requestManager; } @NonNull private SupportRequestManagerFragment getSupportRequestManagerFragment(@NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) { // 搜索是否已经添加了隐藏的Fragment SupportRequestManagerFragment current = (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);//1 if (current == null) { // 从缓存中找 current = pendingSupportRequestManagerFragments.get(fm);// 2 // 还是没有找到,就直接创建一个Fragment if (current == null) { current = new SupportRequestManagerFragment(); current.setParentFragmentHint(parentHint); // 如果当前activity正在显示 if (isParentVisible) { current.getGlideLifecycle().onStart(); } // 加入缓存 pendingSupportRequestManagerFragments.put(fm, current); // 开始fragment事务,标志设置为FRAGMENT_TAG fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss(); handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget(); } } return current; }

1、搜索是否已经添加了隐藏的Fragment到当前的Activity中,如果已经添加过了是由缓存的。
2、如果在当前activity,已经添加了隐藏的Fragment,就尝试从隐藏的Fragment中搜索RequestManager, 如果没有找到,就调用RequestManager工厂创建一个RequestManager,并添加到隐藏的Fragment中,然后返回RequestManager实例。 注意:其实一个Activity就存在一个RequestManager,它们的关系是activity-SupportRequestManagerFragment-RequestManager一一对应。

为什么需要使用pendingRequestManagerFragments?

为什么需要使用pendingRequestManagerFragments这样一个集合来临时存储一下fragment,然后又马上通过handler发送消息移除?这其实是跟主线程的Looper机制和Fragment的事务机制有关的,Fragment事务也是通过Handler处理的。我们知道,android中的主线程是一个闭环,通过Handler发送消息到MessageQueue,然后通过Looper轮询获取消息并交给Handler处理,我们来看如下常见场景,这里所说的是在线程中,如果是子线程,那么不会有添加Fragment这一步,也就是放弃监听生命周期。

Glide.with(this).load(url_1).into(mImageView_1);//1
Glide.with(this).load(url_2).into(mImageView_2);//2

看看这两行代码的Handler消息处理图


handler.png

当我们执行注释1代码时:fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
时对应m1,执行handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();以此类推,但是Handler中MessageQueue是同步取出Message处理,它一般会先执行m1-->r1 -->m2 -->r2,所以Glide为了保证RootFragment的唯一性,加上临时缓存,上面两行代码时同步执行,当第一行执行完那么缓存中必然存在rootfragment。

到此为止就已经创建你好RequestManager了,也就是Glide的整个构建流程完毕,有的读者可能会发现Glide的构建怎么没有,下面就开始。

大家还记得 getRetriever(context)方法中有这么一行

 Glide glide = Glide.get(context);

我们来看看Glide get(@NonNull Context context)源码

private static volatile Glide glide;
/**
 * Get the singleton.
* 单例双重校验
 */
@NonNull
public static Glide get(@NonNull Context context) {
    if (glide == null) {
        synchronized (Glide.class) {
            if (glide == null) {
                checkAndInitializeGlide(context);
            }
        }
    }
    return glide;
}

 private static void checkAndInitializeGlide(@NonNull Context context) {
    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的线程中,一个或多个类可以多次调用Glide.get(context)。
如果没有这个检查,那些调用可能会触发无限递归。就是避免重复初始化Glide对象

下面就是Glide初始化真正的逻辑:

 /**
 * 首先找到@GlideModel注解生成的类GeneratedAppGlideModuleImpl
 * 
 * @param context
 * @param builder
 */
private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
    //获取 applicationContext
    Context applicationContext = context.getApplicationContext();
    // 找到@GlideModel注解生成的类如GeneratedAppGlideModuleImpl
    GeneratedAppGlideModule annotationGeneratedModule = getAnnotationGeneratedGlideModules();
    /**
     * 
     * 
     * 会触发每个Module包括我们自定义的Module中的applyOptions
     *
     * 在GlideBuilder中的biuld方法,每一个默认配置都是判断null,所以我们可以在我们的自定义Module中修改Glide的配置
     *
     */
    if (annotationGeneratedModule != null) {
        annotationGeneratedModule.applyOptions(applicationContext, builder);
    }
    // 构建Glide
    Glide glide = builder.build(applicationContext);

    // 注册组件,例如:替换默认HttpUrlConnection为OkHttp以及其他组件,当然这些是可以通过注解来完成的,详细请看官方的demo
    if (annotationGeneratedModule != null) {
        annotationGeneratedModule.registerComponents(applicationContext, glide, glide.registry);
    }
    applicationContext.registerComponentCallbacks(glide);
    Glide.glide = glide;
}

首先找到@GlideModel注解生成的类GeneratedAppGlideModuleImpl,并且会触发每个Module包括我们自定义的Module中的applyOptions,以便我们修改Glide的默认配置。也就是说当你调用with方法时,就已经初始化Glide

再看看initializeGlide方法中初始化相关的配置GlideBiulder,这里使用构建模式

 // 构建Glide
 Glide glide = builder.build(applicationContext);

GlideBuilder:

private final Map, TransitionOptions> defaultTransitionOptions = new ArrayMap<>();
//  负责启动负载并管理活动和缓存资源。
private Engine engine;
// Bitmap 复用池(享元模式)
private BitmapPool bitmapPool;

private ArrayPool arrayPool;

// 内存管理计算器或者策略
private MemorySizeCalculator memorySizeCalculator;
private MemoryCache memoryCache;

// Glide 资源线程池
private GlideExecutor sourceExecutor;

// 磁盘缓存线程池
private GlideExecutor diskCacheExecutor;
// 磁盘缓存工厂
private DiskCache.Factory diskCacheFactory;

// 网络状态监视器工厂
private ConnectivityMonitorFactory connectivityMonitorFactory;
private int logLevel = Log.INFO;
// 默认请求项
private RequestOptions defaultRequestOptions = new RequestOptions();
@Nullable
private RequestManagerFactory requestManagerFactory;
//执行动画的线程池
private GlideExecutor animationExecutor;
private boolean isActiveResourceRetentionAllowed;
@Nullable
private List> defaultRequestListeners;
private boolean isLoggingRequestOriginsEnabled;

出了这些成员变量之外还有就是这些变量的setxx方法,我就不一一列出来,重点看看biuld方法。

 /**
 * 其实每次判断是否为null就是不应该重复初始化,这也给我们在自定义Model修改Glide的默认配置
 *
 * @param context
 * @return
 */
@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(),
                        animationExecutor,
                        isActiveResourceRetentionAllowed);
    }

    if (defaultRequestListeners == null) {
        defaultRequestListeners = Collections.emptyList();
    } else {
        defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
    }

    //一组静态方法,用于创建新的RequestManagers或从活动和片段中(Retriever)检索现有的RequestManager。
    // RequestManager 描述图片加载请求管理者,例如:感知声明周期取消请求
    RequestManagerRetriever requestManagerRetriever = new RequestManagerRetriever(requestManagerFactory);

    // 创建GLide对象
    return new Glide(
            context,
            engine,
            memoryCache,
            bitmapPool,
            arrayPool,
            requestManagerRetriever,
            connectivityMonitorFactory,
            logLevel,
            defaultRequestOptions.lock(),
            defaultTransitionOptions,
            defaultRequestListeners,
            isLoggingRequestOriginsEnabled);
}

其实Glide的构建是相当复杂的,包括各种线程池的配置以及各种复用池的构建,通过GlideBuilder构建Glide,RequestManager见名思意就是检索RequestManager即在activity或者Fragment中检索是否存在,否则直接创建。

你可能感兴趣的:(Glide源码分析之Glide和RequestManager构建过程)