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() {

                @Override

                public boolean onException(Exception e, String model, Target target,

                    boolean isFirstResource) {

                    return false;

                }

 

                @Override

                public boolean onResourceReady(GlideDrawable resource, String model,

                    Target 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 {

 

    private final ModelCache modelCache;

 

    public static class Factory implements ModelLoaderFactory {

        private final ModelCache modelCache = new ModelCache(500);

 

        @Override

        public ModelLoader 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; 

    } 

 

}

更多相关文章

  1. android图像绘制(六)——获取本地图片或拍照图片
  2. android 辅助工具类—— 图片缓冲池
  3. Android(安卓)TextView实现点击展开动画效果
  4. android 拍照或者图库选择 压缩后 图片 上传
  5. android 9.png 图片制作
  6. Handler, Looper, MessageQueue, Message源码详细分析
  7. Android(安卓)多进程编程 15问15答!
  8. setContentView( )方法
  9. Android开发之异步详解(二)之AsyncTask

随机推荐

  1. Android点击事件隐藏软键盘
  2. Android Studio:常见使用问题处理
  3. MediaScanner与音乐信息扫描==
  4. 打开app弹出欢迎界面,然后自动跳转到主界
  5. 清除手机图案解锁(执行adb命令工具类)
  6. Android 中主Activity和任一Activity进行
  7. 将Android(安卓)Activity设置成对话框式
  8. android中System.exit(0)和System.exit(1
  9. 《Android开发从零开始》——43.Menu使用
  10. android如何阻止app_name在标题栏中闪现