Android 腾讯面试Glide源码解析 3分钟手写最牛框架 看完成牛逼哄哄

Android 腾讯面试Glide源码解析 3分钟手写最牛框架 看完成牛逼哄哄

https://blog.csdn.net/WHB20081815/article/details/88619371

Android 百度面试Evenbus3.0源码解析 3分钟手写最牛框架 看完成大神

https://blog.csdn.net/WHB20081815/article/details/88618798

Android 阿里面试OkHttp源码解析 最牛框架 看完成大神

https://blog.csdn.net/WHB20081815/article/details/88618460

1.Glide基本使用

2.Glide4.0特性

3.Glide的缓存机制

4.Glide的回调与监听

5.Glide强大的图片变换功能

6.Glide修改配置

7.Glide封装okhttp 添加下载进度

8.Glide和其他图片加载框架的优缺点比较

Glide.with(this).load(url).into(imageView);

源码解析:

Glide最基本的用法就是三步走,先with(),再load(),最后into()

1. with()

总结:得到RequestManager

接下来我们看传入非Application参数的情况。不管你在Glide.with()方法中传入的是Activity、FragmentActivity、v4包下的Fragment、还是app包下的Fragment,最终的流程都是一样的,那就是会向当前的Activity当中添加一个隐藏的Fragment。具体添加的逻辑是在上述代码的第117行和第141行,分别对应的app包和v4包下的两种Fragment的情况。那么这里为什么要添加一个隐藏的Fragment呢?因为Glide需要知道加载的生命周期。很简单的一个道理,如果你在某个Activity上正在加载着一张图片,结果图片还没加载出来,Activity就被用户关掉了,那么图片还应该继续加载吗?当然不应该。可是Glide并没有办法知道Activity的生命周期,于是Glide就使用了添加隐藏Fragment的这种小技巧,因为Fragment的生命周期和Activity是同步的,如果Activity被销毁了,Fragment是可以监听到的,这样Glide就可以捕获这个事件并停止图片加载了

--------------------- 

首先,调用Glide.with()方法用于创建一个加载图片的实例。with()方法可以接收Context、Activity或者Fragment类型的参数。也就是说我们选择的范围非常广,不管是在Activity还是Fragment中调用with()方法,都可以直接传this。那如果调用的地方既不在Activity中也不在Fragment中呢?也没关系,我们可以获取当前应用程序的ApplicationContext,传入到with()方法当中。注意with()方法中传入的实例会决定Glide加载图片的生命周期,如果传入的是Activity或者Fragment的实例,那么当这个Activity或Fragment被销毁的时候,图片加载也会停止。如果传入的是ApplicationContext,那么只有当应用程序被杀掉的时候,图片加载才会停止。

2. load() 调用的是 RequestManager.load()

总结;最终load()方法返回的其实就是一个DrawableTypeRequest对象

3. into()

如果说前面两步都是在准备开胃小菜的话,那么现在终于要进入主菜了,因为into()方法也是整个Glide图片加载流程中逻辑最复杂的地方。

Glide的缓存功能,大部分都是在load()方法中进行的

load()也有很多重载的方法,它可以加载网络图片,本地图片,gif(动态图)图,Uri,File,

 

 

 

 

 

Glide的缓存机制

Glide又将它分成了两个模块,一个是内存缓存,一个是硬盘缓存。

Glide内存缓存的实现自然也是使用的LruCache算法。不过除了LruCache算法之外,Glide还结合了一种弱引用的机制,共同完成了内存缓存功能

可以看到,这里首先会将缓存图片从activeResources中移除,然后再将它put到LruResourceCache当中。

这样也就实现了正在使用中的图片使用弱引用来进行缓存,不在使用中的图片使用LruCache来进行缓存的功能。

这就是Glide内存缓存的实现原理。

Engine ----EngineResourceFactory-----EngineResource

缓存的计数机制

EngineResource是用一个acquired变量用来记录图片被引用的次数,调用acquire()方法会让变量加1,调用release()方法会让变量减1

硬盘缓存

首先,和内存缓存类似,硬盘缓存的实现也是使用的LruCache算法,而且Google还提供了一个现成的工具类DiskLruCache。

当然,Glide是使用的自己编写的DiskLruCache工具类,但是基本的实现原理都是差不多的。

decodeFromCache

 

Glide.with(this) .load(new MyGlideUrl(url)) .into(imageView);

玩转Glide的回调与监听

得到不同的listener(),可以自己封装

public void loadImage(View view) {

    String url = "http://cn.bing.com/az/hprichbg/rb/TOAD_ZH-CN7336795473_1920x1080.jpg";

    Glide.with(this)

            .load(url)

            .listener(new RequestListener<String, GlideDrawable>() {

                @Override

                public boolean onException(Exception e, String model, Target<GlideDrawable> target,

                    boolean isFirstResource) {

                    return false;

                }

 

                @Override

                public boolean onResourceReady(GlideDrawable resource, String model,

                    Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {

                    return false;

                }

            })

            .into(imageView);

}

Glide强大的图片变换功能

颜色,尺寸,滤镜的修改

 

Glide.with(this) .load(url) .transform(new CircleCrop(this)) .into(imageView);

Glide修改配置

把缓存的默认路径相关修改 

String url = "http://guolin.tech/book.png";

Glide.with(this)

     .load(url)

     .skipMemoryCache(true)

     .diskCacheStrategy(DiskCacheStrategy.NONE)

     .into(imageView);

--------------------- 

Glide  自定义组件,把网络框架改成http

 

我们知道了Glide内部HTTP通讯组件的底层实现是基于HttpUrlConnection来进行定制的。但是HttpUrlConnection的可扩展性比较有限,我们在它的基础之上无法实现监听下载进度的功能,因此今天的第一个大动作就是要将Glide中的HTTP通讯组件替换成OkHttp。

首先来看一下Glide中目前有哪些组件吧,在Glide类的构造方法当中,如下所示:

 

public class Glide {

 

    Glide(Engine engine, MemoryCache memoryCache, BitmapPool bitmapPool, Context context, DecodeFormat decodeFormat) {

        ...

        register(File.class, ParcelFileDescriptor.class, new FileDescriptorFileLoader.Factory());

        register(File.class, InputStream.class, new StreamFileLoader.Factory());

        register(int.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());

        register(int.class, InputStream.class, new StreamResourceLoader.Factory());

        register(Integer.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());

        register(Integer.class, InputStream.class, new StreamResourceLoader.Factory());

        register(String.class, ParcelFileDescriptor.class, new FileDescriptorStringLoader.Factory());

        register(String.class, InputStream.class, new StreamStringLoader.Factory());

        register(Uri.class, ParcelFileDescriptor.class, new FileDescriptorUriLoader.Factory());

--------------------- 

register(GlideUrl.class, InputStream.class, new HttpUrlGlideUrlLoader.Factory());

 

public class HttpUrlGlideUrlLoader implements ModelLoader<GlideUrl, InputStream> {

 

    private final ModelCache<GlideUrl, GlideUrl> modelCache;

 

    public static class Factory implements ModelLoaderFactory<GlideUrl, InputStream> {

        private final ModelCache<GlideUrl, GlideUrl> modelCache = new ModelCache<GlideUrl, GlideUrl>(500);

 

        @Override

        public ModelLoader<GlideUrl, InputStream> build(Context context, GenericLoaderFactory factories) {

            return new HttpUrlGlideUrlLoader(modelCache);

        }

 

        @Override

        public void teardown() {

        }

    }

实现带进度的Glide图片加载功能

实现下载进度监听

 

那么,将HTTP通讯组件替换成OkHttp之后,我们又该如何去实现监听下载进度的功能呢?这就要依靠OkHttp强大的拦截器机制了。

 

我们只要向OkHttp中添加一个自定义的拦截器,就可以在拦截器中捕获到整个HTTP的通讯过程,然后加入一些自己的逻辑来计算下载进度,这样就可以实现下载进度监听的功能了。

 

拦截器属于OkHttp的高级功能,不过即使你之前并没有接触过拦截器,我相信你也能轻松看懂本篇文章的,因为它本身并不难。

 

确定了实现思路之后,那我们就开始动手吧。首先创建一个没有任何逻辑的空拦截器,新建ProgressInterceptor类并实现Interceptor接口,代码如下所示:

 

public class ProgressInterceptor implements Interceptor { 

 

    @Override 

    public Response intercept(Chain chain) throws IOException {

        Request request = chain.request(); 

        Response response = chain.proceed(request); 

        return response; 

    } 

 

}

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android图片框架Glide-3.7.0(最新,很强大),超好用的图片框架(包含jar和源码Glide 是一个高效、开源、 Android设备上的媒体管理框架,它遵循BSD、MIT以及Apache 2.0协议发布。Glide具有获取、解码和展示视频剧照、图片、动画等功能,它还有灵活的API,这些API使开发者能够将Glide应用在几乎任何网络协议栈里。创建Glide的主要目的有两个,一个是实现平滑的图片列表滚动效果,另一个是支持远程图片的获取、大小调整和展示。近日,Glide 3.0发布,现已提供 jar包下载 ,同时还支持使用Gradle以及Maven进行构建。该版本包括很多值得关注的新功能,如支持Gif 动画和视频剧照解码、智能的暂停和重新开始请求、支持缩略图等,具体新增功能如下如下: GIF 动画的解码 :通过调用Glide.with(context).load(“图片路径“)方法,GIF动画图片可以自动显示为动画效果。如果想有更多的控制,还可以使用Glide.with(context).load(“图片路径“).asBitmap()方法加载静态图片,使用Glide.with(context).load(“图片路径“).asGif()方法加载动画图片 本地视频剧照的解码: 通过调用Glide.with(context).load(“图片路径“)方法,Glide能够支持Android设备中的所有视频剧照的加载和展示 缩略图的支持: 为了减少在同一个view组件里同时加载多张图片的时间,可以调用Glide.with(context).load(“图片路径“).thumbnail(“缩略比例“).into(“view组件“)方法加载一个缩略图,还可以控制thumbnail()中的参数的大小,以控制显示不同比例大小的缩略图 Activity 生命周期的集成: 当Activity暂停和重启时,Glide能够做到智能的暂停和重新开始请求,并且当Android设备的连接状态变化时,所有失败的请求能够自动重新请求 转码的支持: Glide的toBytes() 和transcode() 两个方法可以用来获取、解码和变换背景图片,并且transcode() 方法还能够改变图片的样式 动画的支持: 新增支持图片的淡入淡出动画效果(调用crossFade()方法)和查看动画的属性的功能 OkHttp 和Volley 的支持: 默认选择HttpUrlConnection作为网络协议栈,还可以选择OkHttp和Volley作为网络协议栈 其他功能: 如在图片加载过程中,使用Drawables对象作为占位符、图片请求的优化、图片的宽度和高度可重新设定、缩略图和原图的缓存等功能

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值