本文共 3115 字,大约阅读时间需要 10 分钟。
glide源码分析:
一。Glide的with方法可以接收五种类型的Context
1.public static RequestManager with(Context context) {
RequestManagerRetriever retriever = RequestManagerRetriever.get(); return retriever.get(context); }
2.public static RequestManager with(Activity activity) {
RequestManagerRetriever retriever = RequestManagerRetriever.get(); return retriever.get(activity); }
3.public static RequestManager with(FragmentActivity activity) {
RequestManagerRetriever retriever = RequestManagerRetriever.get(); return retriever.get(activity); }
4.public static RequestManager with(android.app.Fragment fragment) {
RequestManagerRetriever retriever = RequestManagerRetriever.get(); return retriever.get(fragment); }
5.public static RequestManager with(Fragment fragment) {
RequestManagerRetriever retriever = RequestManagerRetriever.get(); return retriever.get(fragment); }
可以看到,with()方法的重载种类非常多,既可以传入Activity,也可以传入Fragment或者是Context。
每一个with()方法重载的代码都是先调用RequestManagerRetriever的静态get()方法得到一个RequestManagerRetriever对象, (rui kuai si te mai nei zher rei tie wer) 这个静态get()方法就是一个单例实现, 然后再调用RequestManagerRetriever的实例get()方法,去获取RequestManager对象。分析RequestManagerRetriever的实例get()方法中可以发现:
RequestManagerRetriever类中看似有很多个get()方法的重载,什么Context参数,Activity参数,Fragment参数等等, 实际上只有两种情况而已,即传入Application类型的参数,和传入非Application类型的参数。(1).传入Application参数的情况。如果在Glide.with()方法中传入的是一个Application对象,
那么这里就会调用带有Context参数的get()方法重载, 然后调用getApplicationManager()方法来获取一个RequestManager对象。 其实这是最简单的一种情况,因为Application对象的生命周期即应用程序的生命周期, 因此Glide并不需要做什么特殊的处理,它自动就是和应用程序的生命周期是同步的, 如果应用程序关闭的话,Glide的加载也会同时终止。(2).传入非Application参数的情况。不管你在Glide.with()方法中传入的是Activity、FragmentActivity、v4包下的Fragment、还是app包下的Fragment,
最终的流程都是一样的,那就是会向当前的Activity当中添加一个隐藏的Fragment。 分别对应的app包和v4包下的两种Fragment的情况。 那么这里为什么要添加一个隐藏的Fragment呢? 因为Glide需要知道加载的生命周期。 那么图片还应该继续加载吗?当然不应该。 可是Glide并没有办法知道Activity的生命周期, 于是Glide就使用了添加隐藏Fragment的这种小技巧, 因为Fragment的生命周期和Activity是同步的, 如果Activity被销毁了,Fragment是可以监听到的,这样Glide就可以捕获这个事件并停止图片加载了。二。 load()
load()方法,这个方法中的逻辑是非常简单的,只有一行代码,就是先调用了fromString()方法,
fromString()方法会返回一个DrawableTypeRequest对象,再调用load()方法,然后把传入的图片URL地址传进去。 DrawableTypeRequest中并没有load()方法,很容易就能猜想到,load()方法是在父类当中的。 DrawableTypeRequest的父类是DrawableRequestBuilder,里面有很多方法比如placeholder()、error()、override()等。 三。 into()into()方法也是整个Glide图片加载流程中逻辑最复杂的地方。
into()方法中并没有任何逻辑,只有一句super.into(view)。 那么很显然,into()方法的具体逻辑都是在DrawableRequestBuilder的父类GenericRequestBuilder当中了。先是调用了glide.buildImageViewTarget()方法,这个方法会构建出一个Target对象,
这个Target就是一个GlideDrawableImageViewTarget对象,是用来最终展示图片用的。 在GlideDrawableImageViewTarget的onResourceReady()方法中做了一些逻辑处理, 包括如果是GIF图片的话,就调用resource.start()方法开始播放图片。 GlideDrawableImageViewTarget的setResource()方法,没错,调用的view.setImageDrawable()方法, 而这个view就是ImageView。 代码执行到这里,图片终于也就显示出来了。Glide默认的Bitmap格式是RGB_565,比Picasso默认的ARGB_8888格式的内存开销要小一半;
Picasso缓存的是全尺寸的(,而Glide缓存的是跟ImageView尺寸相同的(即56*56和128*128是两个缓存) 。Glide的这种默认的缓存机制有一个优点,就是它可以加快图片加载的速度
而Picasso会造成一定的延迟,因为它在加载到imageview的时候,总是需要调整大小。而且Glide可以加载Gif图,Picasso不可以。
Fresco非常强大,自带内存回收机制。图片不可见时,会及时释放内存。 自带三级缓存,也支持缩略图加载,gif图等。 但是Fresco在使用起来有些麻烦,因为他只能用内置的一个SimpleDraweeView代替ImageView来实现这些功能,用起来比较麻烦, 所占用空间比较大。 而Glide 轻量级,效率高。自带缓存机制。
转载地址:http://lutli.baihongyu.com/