安卓Glide那些事情面试,一篇全部搞定

一.Glide有几级缓存???

Gllide的四级缓存流程图:
在这里插入图片描述
通过上面这个流程图,我们可以知道Glide的缓存可以分为四级,第一个是ActiveResources,第二个是MemoryCache内存缓存,第三个是DiskCache磁盘缓存,第四个是网络获取。ActiveResources使用弱引用,内存缓存和磁盘缓存使用LruCache近期最少使用原则

Gllide的源码分析流程:
在这里插入图片描述
我们主要讨论这三个缓存,不讨论网络缓存
范围:
1、活动缓存:在某个Activity范围,页面退出该缓存就不存在
2、内存缓存:某个App范围,应用完全退出就不存在
3、磁盘缓存:整个系统,只要不删除数据,就一直存在

作用:
1、活动缓存:分担内存缓存的负担,
2、内存缓存:加快数据读取
3、磁盘缓存:进行永久性保持
活动缓存的说明
1、活动缓存并不是我们熟悉的内存缓存,是Glide自己定义的一种缓存策略。
2、本质上就是HasMap,用了一次就缓存,以后需要就直接拿,不需要就清除这个缓存。
3、该策略的存在也是为了及时释放内存,不需要等等整个应用退出再释放内存,减轻应用内存负担。
4、活动缓存比内存缓存小,如果活动缓存满了,会自动写到内存缓存。
5、系统会对内存缓存进行自动管理,只要不是快速存放大内存文件,并且不一直占有内存对象,都不会内存溢出。
内存缓存的说明
内存缓存是系统自身会管理的,但是可以继承LruCache,做进一步管理
磁盘缓存的说明
1、磁盘缓存本质是本地文件缓存,但是通过普通的文件写入读取效率不高。
2、Glide中使用了DiskLruCache框架进行数据保存和读取。
3、效率高的主要原因是:磁盘缓存对图片文件进行了加密和压缩处理。
总结
1、优先从活动缓存获取
2、活动缓存没有就再内存缓存中寻找
3、内存缓存没有,就去磁盘缓存读取
4、磁盘缓存没有就去网络获取本地文件读取

二.Gllide源码分析

https://blog.csdn.net/nufuli123/article/details/123806389

三.内存缓存和磁盘缓存LruCache算法

内存缓存:LruCache算法中LinkedHashMap
磁盘缓存: journal日志清单文件

磁盘读写也是用的LRU算法。但是这个和内存的LRU算法有一点小区别。为什么呢?因为内存缓存是我们运行的时候,程序加载内存里面的资源,可以直接通过一个LinkedHashMap去实现。但是磁盘不同,我总不可能吧所有磁盘的资源读出来然后加载在内存里面吧,这样的话,肯定会引发oom了。那么Glide是怎么做磁盘的LRU的呢?

Glide 是使用一个日志清单文件来保存这种顺序,DiskLruCache 在 APP 第一次安装时会在缓存文件夹下创建一个 journal 日志文件来记录图片的添加、删除、读取等等操作,后面每次打开 APP 都会读取这个文件,把其中记录下来的缓存文件名读取到 LinkedHashMap 中,后面每次对图片的操作不仅是操作这个 LinkedHashMap 还要记录在 journal 文件中. journal 文件内容如下图:

data/data/应用包名/cache/。。。。。
在这里插入图片描述
journal文件:在这里插入图片描述

四.Gllide基本使用

Glide.with(this).load(url).into(imageView);//默认是开启内存缓存和磁盘缓存的。
1.内存缓存:

Glide.with(this)
     .load(url)
     .skipMemoryCache(true)//关闭内存缓存
     .into(imageView);

2.磁盘缓存:

Glide.with(this)
     .load(url)
     .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)//磁盘缓存
     .into(imageView);

一个 diskCacheStrategy( ) 方法就可以调整他的硬盘缓存策略。其中可以传入的参数有四种

DiskCacheStrategy.ALL :     //表示既缓存原始图片,也缓存转换过后的图片。
DiskCacheStrategy.NONE:     //表示不缓存任何内容。
DiskCacheStrategy.RESOURCE: //表示只缓存原始图片。
DiskCacheStrategy.RESULT:   //(已过期,新api4.11修改为后面两个)表示只缓存转换过后的图片(默认选项)。
DiskCacheStrategy.DATA:     //表示只缓存转换过后的图片。
DiskCacheStrategy.AUTOMATIC  //表示智能判断选择模式(默认选项)。

3.清理缓存:

Glide.get(GlideActivity.this).clearMemory();//清除内存缓存
new Thread(new Runnable() {
                        @Override
                        public void run() {
                            Glide.get(GlideActivity.this).clearDiskCache();//清除SD卡缓存
                        }
                    }).start();


五.Gllide高级使用:配置

依赖:

  implementation 'com.squareup.okhttp3:logging-interceptor:3.9.1'
    // Glide集成OkHttp时需要使用的库,库已经将需要适配Okhhtp的大部分代码封装,注意如果之前已经使用了okhttp依赖注释掉
    implementation "com.github.bumptech.glide:okhttp3-integration:4.13.0"
    implementation 'com.github.bumptech.glide:glide:4.13.0'
    kapt 'com.github.bumptech.glide:compiler:4.13.0'//Glide注解处理器的依赖

权限:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

1.配置内存和磁盘缓存大小

@GlideModule
class MyGlideModule: AppGlideModule() {
    override fun applyOptions(context: Context, builder: GlideBuilder) {
       
        var memorySizeCalculator = MemorySizeCalculator.Builder(context).build()
        //设置内存缓存大小
        builder.setMemoryCache(LruResourceCache(memorySizeCalculator.memoryCacheSize.toLong()))
        //设置磁盘缓存目录和大小,默认目录:"image_manager_disk_cache"  默认大小:250 * 1024 * 1024
        builder.setDiskCache(InternalCacheDiskCacheFactory(context,"image",500 * 1024 * 1024))
    }
}

2.配置okhttp

glide默认使用HttpUrlConnection请求网络图片

@GlideModule
class OkHttpLibraryGlideModule: LibraryGlideModule() {
    override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
        var client = OkHttpClient.Builder()
            .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
            .build()
        registry.replace(GlideUrl::class.java,InputStream::class.java,OkHttpUrlLoader.Factory(client))

    }
}

3.配置https认证

使用上面的代码去加载一些网络上的https图片一般是没有问题的,没问题是因为网络上的https使用的证书一般是权威机构颁发的证书,而这些权威机构的根证书在手机出厂时就已经预装在手机里面了,所以我们加载https图片时会自动完成认证,但是突然有一天,我们公司的网络请求也改成了Https了,用的是自定义证书,并不是权威机构颁发的,所以这个时候加载公司的https的图片时就加载失败了,异常如下:

Glide: Load failed for https://192.168.1.250:8080/cat.jpg with size [1080x162]
class com.bumptech.glide.load.engine.GlideException: Failed to load resource
There was 1 cause:
javax.net.ssl.SSLHandshakeException(java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.)

看到CertPathValidatorException(证书路径验证器异常)不用我多说应该也知道是什么原理导致的了。

@GlideModule
class OkHttpLibraryGlideModule: LibraryGlideModule() {
    override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
        var client = OkHttpClient.Builder()
            .sslSocketFactory(sSLSocketFactory, trustManager)//https认证
            .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
            .build()
        registry.replace(GlideUrl::class.java,InputStream::class.java,OkHttpUrlLoader.Factory(client))
    }

    /** 获取一个SSLSocketFactory */
    val sSLSocketFactory: SSLSocketFactory
        get() = try {
            val sslContext = SSLContext.getInstance("SSL")
            sslContext.init(null, arrayOf(trustManager), SecureRandom())
            sslContext.socketFactory
        } catch (e: Exception) {
            throw RuntimeException(e)
        }

    /** 获取一个忽略证书的X509TrustManager */
    val trustManager: X509TrustManager
        get() = object : X509TrustManager {
            override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) { }
            override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) { }
            override fun getAcceptedIssuers(): Array<X509Certificate> { return arrayOf() }
        }
}

4.使用

最后还有一步,第2步创建的类中使用了注解,Glide会自动生成一个GlideApp的类,这个类就是使用了我们配置的OkHttp的,所以在下载图片时,我们要使用GlideApp来代替之前的Glide类,如下:

GlideApp.with(this)
                .load("https://192.168.1.250:8080/cat.jpg")
                .centerCrop()
                .placeholder(R.mipmap.ic_launcher)
                .into(imageView) 
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值