zoukankan      html  css  js  c++  java
  • Glide源码解析一,初始化

    转载请标明出处:https:////www.cnblogs.com/tangZH/p/12409849.html

    更多精彩文章:http://77blogs.com/?p=269

    Glide作为一个强大的图片加载框架,已经被android官方使用,所以,明白Glide的加载流程以及原理对加深我们对glide的理解是很重要的。

    本文基于glide 4.11

    Glide.with(this).load("").into(new ImageView(this));

     

    我们从这一句入手,先看看Glide的初始化过程,也就是Glide.with(this)这个方法。

    一、单例实例化

     

     

    可以看到里面有多个重载方法,最常用的是这个,这些方法最终返回的是RequestManager

    都一致调用了getRetriever(...).get(view)

     

    我们看一下getRetriever(...)里面做了什么。

     

     

    getRequestManagerRetriever()返回的是一个RequestManagerRetriever,我们主要看的是Glide.get(context)

     

    可以看到Glide.get(context)里面进行了初始化的操作,它是我们熟悉的单例模式。最终会调用

     

    二、GlideModule配置加载

    上面的get方法中,我们需要注意这一句:

    GeneratedAppGlideModule annotationGeneratedModule =
              getAnnotationGeneratedGlideModules(context.getApplicationContext());

     

    点进去可以看到关键部分的代码为

     

     Glide提供给我们自定义加载组件的方式,在Glide 3x中,我们首先会定义一个继承于GlideModule的类,然后在项目的AndroidMenifest.xml中进行指定:

    <meta-data android:name="com.test.GlideConfiguration"
               android:value="GlideModule"/>
    而在Glide4中,提供另外一个配置的模式,那就是注解,并且不再继承GlideModule,而是继承AppGlideModule和LibraryGlideModule,分别对应Application和Library,使用@GlideModule注解进行标记。而Glide3.x中的配置方式已经建议放弃使用。

    getAnnotationGeneratedGlideModules(context.getApplicationContext());便是获取Glide注解自动生产的一个Glide的Module配置器,叫做:

    GeneratedAppGlideModuleImpl

    然后将其作为参数最终传递到initializeGlide方法。

     

    initializeGlide方法:

     

    上面这一段的意思就是:从manifest中解析到我们自定义的GlideModule类,如果判断与注解生成的类重复,那么就可以去掉。

    annotationGeneratedModule.isManifestParsingEnabled()

    判断是否还支持Glide 3x的在AndroidMenifest.xml中进行指定的方式,默认是返回true,说明现在还是支持的。

     

    接着以上代码,Glide将逐个调用剩下的GlideModule,并回调applyOptionsregisterComponents接口,这时,用户配置的GlideModule就会被调用,同时用户设置的参数也就被配置到Glide中。

     

    源码中获取的通过注解生成的GlideModule只有一个,这也说明了我们只能通过注解配置一次。
     
    三、构建Glide
    Glide glide = builder.build(applicationContext);

     

     

      build方法里面是对glide的各种配置,比如上面的:

    1、加载源数据的线程池

    2、加载磁盘缓存中数据的线程池(不能用来加载url网络数据)

    3、动画加载请求器

    4、内存计算器

    5、网络状态检测器

    6、bitmap缓存池(避免不断不断创建与回收bitmap导致内存抖动)

    7、数组资源缓存池
    8、内存缓存,缓存完成加载和显示的图片数据资源
    9、本地磁盘缓存,默认存储在app内部私密目录
     
    然后创建图片加载引擎。

     

    最后再将上面的缓存池,引擎等作为参数,构建一个Glide

     

     这个构造函数非常长,我们只挑一些重点的来讲,其它的可以类推:

    1、创建各种decoder,也就是解码器,比如:

    ByteBufferGifDecoder byteBufferGifDecoder =
        new ByteBufferGifDecoder(context, imageHeaderParsers, bitmapPool, arrayPool);

    将ByteBuffer解码为GifDrawable。

     

    ResourceDrawableDecoder resourceDrawableDecoder = new ResourceDrawableDecoder(context);

    将资源uri解码为Drawable

     

    2、创建各种factory,即模型装换器,比如:

    ResourceLoader.StreamFactory resourceLoaderStreamFactory =
        new ResourceLoader.StreamFactory(resources);

    将Android资源ID转换为Uri,在加载成为InputStream

     

    ResourceLoader.UriFactory resourceLoaderUriFactory = new ResourceLoader.UriFactory(resources);

    将资源ID转换为Uri

     

    3、创建各种Transcoder,即转码器,比如

    BitmapBytesTranscoder bitmapBytesTranscoder = new BitmapBytesTranscoder();

    将Bitmap转码为Byte arrays

     

    GifDrawableBytesTranscoder gifDrawableBytesTranscoder = new GifDrawableBytesTranscoder();

    将将GifDrawable转码为Byte arrays

     

    4、创建各种encoder,即编码器,比如:

    BitmapEncoder bitmapEncoder = new BitmapEncoder(arrayPool);

    将Bitmap数据缓存为File

     

    5、注册:

     

     如上面,注册将Byte数据缓存为File的编码器,注册将InputStream缓存为File的编码器。将ByteBuffer解码为Bitmap的解码器,将inputStreams解码为Bitmap的编码器。

     

    四、生命周期管理。

    getRetriever(activity).get(activity);中的getRetriever(activity)方法讲解完了,接下来讲get方法,大家就能知道glide是怎么监听图片的生命周期的。

     

     

     

     

     

     

     同样的,get方法也有多个重载方法,方法里面检测,如果是运行在后台线程,那都会调用下面这个方法:

     

    因为不是运行在主线程,所以最终也都会调用:

    getApplicationManager(context),创建一个RequestManager,生命周期与application的一样。

    而如果不是运行在后台线程的话,那么重载方法里面的参数不同,执行的方法也就不同,我且看这一个:

    public RequestManager get(@NonNull Activity activity) 

    传递的参数是activity,那么生命周期应该与Activity一样。

     

    我们点进去fragmentGet方法:

     

    可以看到它首先获取RequestManagerFragment,这其实就是一个fragment,然后获取与之绑定的RequestManager,如果获取不到就说明还没绑定,那么就去构建一个RequestManager,然后与RequestManagerFragment进行绑定。而在构建RequestManager的时候,传进去了一个current.getGlideLifecycle(),这个是Glide的生命周期,可以看出生命周期的管理是在RequestManager中的。那怎么实现与activity的生命周期同步呢?

    接下来就要看看getRequestManagerFragment(fm, parentHint, isParentVisible);这个方法做了什么。

    首先通过tag去找activity中有没有存在对应的fragment,找不到的话就去pendingRequestManagerFragments  这个map中看有没有,还没有的话就去初始化一个RequestManagerFragment。

    再将fragment添加到activity中。

    pendingRequestManagerFragments的作用:

    pendingRequestManagerFragments是为了防止重复添加fragment。因为add方法来添加fragment并不会立即执行,而是被加入任务队列中。它有相关的生命周期是异步进行的,所以如果add之后立马又在相同fragment或者activity环境中调用get方法,那么就很有可能又创建一个新的RequestManagerFragment,所以用pendingRequestManagerFragments在add任务完成前拦截其他的添加操作,在完成后发送消息移除。

    if (isParentVisible) {
              current.getGlideLifecycle().onStart();
            }

     

    如果父布局可见,也就是activity可见,那么开始生命周期的start回调。

    在RequestManagerFragment里面可以看到,fragment的生命周期进行回调的时候就会调用glide自定义的生命周期lifecycle的相应方法。

    也就是说glide是通过往activity中添加fragment,然后监听fragment的生命周期来控制glide的生命周期进行同步

    其它的重载方法类推。

     

     
     

     

  • 相关阅读:
    一行代码更改博客园皮肤
    fatal: refusing to merge unrelated histories
    使用 netcat 传输大文件
    linux 命令后台运行
    .net core 使用 Nlog 配置文件
    .net core 使用 Nlog 集成 exceptionless 配置文件
    Mysql不同字符串格式的连表查询
    Mongodb between 时间范围
    VS Code 使用 Debugger for Chrome 调试vue
    css权重说明
  • 原文地址:https://www.cnblogs.com/tangZH/p/12409849.html
Copyright © 2011-2022 走看看