转载请标明出处:https:////www.cnblogs.com/tangZH/p/12409849.html Glide作为一个强大的图片加载框架,已经被android官方使用,所以,明白Glide的加载流程以及原理对加深我们对glide的理解是很重要的。 本文基于glide 4.11 Glide.with(this).load("").into(new ImageView(this)); 我们从这一句入手,先看看Glide的初始化过程,也就是Glide.with(this)这个方法。 一、单例实例化 可以看到里面有多个重载方法,最常用的是这个,这些方法最终返回的是RequestManager 。 都一致调用了getRetriever(...).get(view)。 我们看一下getRetriever(...)里面做了什么。 如果是在ftragment中调用,要注意fragment还没有attach之前,不能调用getActivity,否则会返回null 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,并回调applyOptions和registerComponents接口,这时,用户配置的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的生命周期进行同步 其它的重载方法类推。 总体流程图: |
|