1. Glide的缓存有哪些
内存缓存和磁盘缓存
2. 缓存对应的实现类是什么
内存缓存:
- ActiveResource
- LruResourceCache
ActiveResource
是使用HaspMap
进行的数据存储.键值是用弱引用进行的包装.为什么要用弱引用,因为他缓存的是正在使用的图片,当页面被销毁了,你还拿着对象的引用,会造成内存泄漏,所以要用弱引用进行包装.
LruResourceCache
他缓存的是所有曾经加载过的图片信息,他和ActiveResource
的区别是,他底层使用了Lru
算法,然后Lru
算法的实现是通过LinkedHashmap
.为什么LruResourceCache
要用到Lru
算法,然后还不用弱引用.因为他缓存的不是正在使用的图片,不会存在内存泄漏的问题.然后如果他也使用了弱引用,就会导致缓存的资源被频繁的清空,也就失去了缓存的意义了.当然,缓存的大小总是有个边界的,所以使用了Lru算法,在超过缓存大小后删除那些最近最少使用的资源.这个实现就是用到了LinkedHashMap
.LinkedHashMap
继承HashMap
,他重写了newNode
方法,键值封装到了LinkedHashMapEntry
里面,维护了一个双向链表.这样我们就能得到我们的插入顺序了.新插入的值是插在链表的尾部的.默认情况下LinkedHashMap
的插入顺序和遍历顺序是一样的,但是我们通过改变accessOrder
值为true
3. 如何全局设置Glide的加载配置,并且他的原理是什么,为什么可以设置一个全局的加载配置
在Glide里,配置信息都是写入BaseRequesOptions
里面.我们每次发起请求通过Glide.with(context)
先获取当前页面的RequestManager
,然后在调用load
创建RequestBuilder
对象,这个对象是每次调用load都会创建一个新的.我们可以看到RequestBuilder
是继承BaseRequestOptions
的.看下对象创建的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class RequestManager{ public RequestBuilder<Drawable> load(@Nullable String string) { return asDrawable().load(string); } public RequestBuilder<Drawable> asDrawable() { return as(Drawable.class); } public <ResourceType> RequestBuilder<ResourceType> as( @NonNull Class<ResourceType> resourceClass) { return new RequestBuilder<>(glide, this, resourceClass, context); } } class RquestBuilder{ protected RequestBuilder( @NonNull Glide glide, RequestManager requestManager, Class<TranscodeType> transcodeClass, Context context) { ---- apply(requestManager.getDefaultRequestOptions()); } }
|
其他都是浮云.重点是RequestBuilder
的构造函数里面的apply
方法.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| public T apply(@NonNull BaseRequestOptions<?> o) { BaseRequestOptions<?> other = o;
if (isSet(other.fields, SIZE_MULTIPLIER)) { sizeMultiplier = other.sizeMultiplier; } if (isSet(other.fields, USE_UNLIMITED_SOURCE_GENERATORS_POOL)) { useUnlimitedSourceGeneratorsPool = other.useUnlimitedSourceGeneratorsPool; } if (isSet(other.fields, USE_ANIMATION_POOL)) { useAnimationPool = other.useAnimationPool; } if (isSet(other.fields, DISK_CACHE_STRATEGY)) { diskCacheStrategy = other.diskCacheStrategy; } if (isSet(other.fields, PRIORITY)) { priority = other.priority; } if (isSet(other.fields, ERROR_PLACEHOLDER)) { errorPlaceholder = other.errorPlaceholder; errorId = 0; fields &= ~ERROR_ID; } if (isSet(other.fields, ERROR_ID)) { errorId = other.errorId; errorPlaceholder = null; fields &= ~ERROR_PLACEHOLDER; } if (isSet(other.fields, PLACEHOLDER)) { placeholderDrawable = other.placeholderDrawable; placeholderId = 0; fields &= ~PLACEHOLDER_ID; } if (isSet(other.fields, PLACEHOLDER_ID)) { placeholderId = other.placeholderId; placeholderDrawable = null; fields &= ~PLACEHOLDER; } if (isSet(other.fields, IS_CACHEABLE)) { isCacheable = other.isCacheable; } if (isSet(other.fields, OVERRIDE)) { overrideWidth = other.overrideWidth; overrideHeight = other.overrideHeight; } if (isSet(other.fields, SIGNATURE)) { signature = other.signature; } if (isSet(other.fields, RESOURCE_CLASS)) { resourceClass = other.resourceClass; } if (isSet(other.fields, FALLBACK)) { fallbackDrawable = other.fallbackDrawable; fallbackId = 0; fields &= ~FALLBACK_ID; } if (isSet(other.fields, FALLBACK_ID)) { fallbackId = other.fallbackId; fallbackDrawable = null; fields &= ~FALLBACK; } if (isSet(other.fields, THEME)) { theme = other.theme; } if (isSet(other.fields, TRANSFORMATION_ALLOWED)) { isTransformationAllowed = other.isTransformationAllowed; } if (isSet(other.fields, TRANSFORMATION_REQUIRED)) { isTransformationRequired = other.isTransformationRequired; } if (isSet(other.fields, TRANSFORMATION)) { transformations.putAll(other.transformations); isScaleOnlyOrNoTransform = other.isScaleOnlyOrNoTransform; } if (isSet(other.fields, ONLY_RETRIEVE_FROM_CACHE)) { onlyRetrieveFromCache = other.onlyRetrieveFromCache; }
if (!isTransformationAllowed) { transformations.clear(); fields &= ~TRANSFORMATION; isTransformationRequired = false; fields &= ~TRANSFORMATION_REQUIRED; isScaleOnlyOrNoTransform = true; }
fields |= other.fields; options.putAll(other.options);
return selfOrThrowIfLocked(); }
|
可以看到apply
方法就是一个拷贝的操作,他将requestManager.getDefaultRequestOptions()
默认配置赋值给了新的RequestBuilder
.所以我们可以操作的点出来了.
我们通过修改getDefultRequestoptions
就可以实现修改全局的GLide加载属性了. 这里我拿修改Glide的编码格式为DecodeFormat.PREFER_RGB_565
来举例.(应用场景:在手机内存太小的手机上,用来减少图片的内存占用).
1 2 3 4 5 6 7 8 9 10 11 12
| @GlideModule class MyGlideModule : AppGlideModule(){ override fun applyOptions(context: Context, builder: GlideBuilder) { super.applyOptions(context, builder) val activityManager:ActivityManager = context.getSystemService(Context.ALARM_SERVICE) as ActivityManager if(activityManager!=null){ var memoryInfo = ActivityManager.MemoryInfo() activityManager.getMemoryInfo(memoryInfo) builder.setDefaultRequestOptions(RequestOptions().format(DecodeFormat.PREFER_RGB_565)) } } }
|
1 2 3
| <meta-data android:name="com.adventure.live.MyGlideModule" android:value="GlideModule" />
|
实现方法就是继承AppGlideModule
重写applyOptions
方法.