分析glide源码后的总结

1.glide的网络请求用的是什么?

httpurlconnection

2.glide如何和activity同步生命周期?

通过创建一个隐藏的fragment,同步activity的生命周期。如果传入的上下文是application,那么glide的请求生命周期和应用一样长。

3.glide的缓存key是如何生成的?

1.缓存原图的话key主要是有url组成
2.缓存转换后的图的key是由width,height,encoder等十个参数生成。

4.glide内存缓存怎么实现的?

内存缓存由两部分组成,由Lrucache算法和弱引用activiResources 一个hashMap集合组成,这个集合存储正在使用的图片。这个hashMap集合可以确保图片不会被lrucache算法回收掉。也就是说glide将正在使用的图片用activeResources保存,不在使用的用LruCache来保存。

5.glide的硬盘缓存

glide磁盘缓存可以缓存原始图片和转换后的图片,如果是原始图片,那么缓存key就是id和signature,如果缓存的是转换后的图片那缓存key是由宽高等十多个参数组成。磁盘缓存使用的DiskLrucache。

6.glide缓存失效问题

当我们请求一张图片的url后面加入了可变token的时候,那么我们glide的缓存就会失效,因为缓存key的组成就有url,解决这个问题可以自定义GlideUrl,重写getCacheKey()这个方法。

7.glide的预加载功能

glide提供了预加载接口,就是preLoad()方法,这个方法有两个重载,一个是加载原始图片大小,一个是指定宽和高,如果使用preLoad()预加载图片,那么需要指定缓存策略为原图,否则再真正显示用into的时候,还是会去网络加载,因为缓存key不一致,获取不到缓存图片。当然into加载的时候也需要指定缓存策略为缓存原图。

8.如何获取缓存图片的路径。

要想获取一个缓存图片的路径可以使用downloadOnly()方法,这个方法会执行下载图片的逻辑,并且下载i 之后是一个文件,可以获取路径,必须在子线程开启下载。

public void downloadImage(View view) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                final Context context = getApplicationContext();
                FutureTarget target = Glide.with(context)
                                                 .load(url)
                                                 .downloadOnly(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);
                final File imageFile = target.get();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(context, imageFile.getPath(), Toast.LENGTH_LONG).show();
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }).start();
}
9.glide的错误调试

glide有一个listener()方法,这个方法在into之前或者preLoad()之前调用,requestListener中的两个方法都有返回值,当都返回false的时候包括错误展位图和正常图片显示才会继续执行。

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);
}

10.glide图片变换导致的充满全屏幕问题
可以通过设置dontTrasform() or override(Target.SIZE_ORIGINSL,Target.SIZE_ORIGINSL) 方法解决。
11.glide模块的自定义
glide支持对一些功能的自定义,以及一些组建的替换。

public class MyGlideModule implements GlideModule {
  @Override
  public void applyOptions(Context context, GlideBuilder builder) {
  }

  @Override
  public void registerComponents(Context context, Glide glide) {
  }
}

通过实现GlideModule可以实现一些功能的自定义和一些自定义组建的替换,applyOptions方法中实现功能的自定义,registerComponents这个方法实现自定义组建的替换,这两个方法互相独立使用。
下面是glide允许自定义的功能列表:

setMemoryCache() 
用于配置Glide的内存缓存策略,默认配置是LruResourceCache。

setBitmapPool() 
用于配置Glide的Bitmap缓存池,默认配置是LruBitmapPool。

setDiskCache() 
用于配置Glide的硬盘缓存策略,默认配置是InternalCacheDiskCacheFactory。

setDiskCacheService() 
用于配置Glide读取缓存中图片的异步执行器,默认配置是FifoPriorityThreadPoolExecutor,也就是先入先出原则。


setResizeService() 
用于配置Glide读取非缓存中图片的异步执行器,默认配置也是FifoPriorityThreadPoolExecutor。

setDecodeFormat() 
用于配置Glide加载图片的解码模式,默认配置是RGB_565。

其中最常见的就是自定义缓存路径和自定义图片编码模式

public class MyGlideModule implements GlideModule {

    public static final int DISK_CACHE_SIZE = 500 * 1024 * 1024;

    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        builder.setDiskCache(new ExternalCacheDiskCacheFactory(context, DISK_CACHE_SIZE));
        builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
    }

    @Override
    public void registerComponents(Context context, Glide glide) {

    }

}

上面这段代码实现了将glide的缓存文件缓存到sd卡,并且指定图片编码模式是ARGB_8888,Android默认是RGB_565.

替换glide组件

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(Uri.class, InputStream.class, new StreamUriLoader.Factory());
        register(URL.class, InputStream.class, new StreamUrlLoader.Factory());
        register(GlideUrl.class, InputStream.class, new HttpUrlGlideUrlLoader.Factory());
        register(byte[].class, InputStream.class, new StreamByteArrayLoader.Factory());

        ...
    }

一般主要可能替换的组件就是网络组件,所以glide给我们提供了非常简单的方式去继承其他的网络库,比如okhttp:

dependencies {
    compile 'com.squareup.okhttp3:okhttp:3.9.0'
    compile 'com.github.bumptech.glide:okhttp3-integration:1.5.0@aar'
}

只需要加入这样的依赖我们的网络库就替换成了okhttp。

参考资料:
glide源码
郭霖glide源码分析

你可能感兴趣的:(分析glide源码后的总结)