前言:
之前的文章中,笔者介绍了很多Glide的使用方法,但是由于Glide框架封装得太好了,很多人在使用的时候,只是知其然不知其所以然,为了不要仅仅成为”cv工程师”,只会复制粘贴,所以这篇文章我们就一起来研究一下Glide的源码,看看Glide到底是怎么将一张图片加载出来的~
Glide 系列目录
- 1.Glide-入门教程
- 2.Glide-占位图以及加载动画
- 3.Glide-加载本地图片
- 4.Glide-加载Gif
- 5.Glide-绑定生命周期
- 6.Glide-内存缓存与磁盘缓存
- 7.Glide-通过Modules定制Glide
- 8.Glide-自定义缓存
- 9.Glide-图片的压缩
- 10.Glide-图片预处理(圆角,高斯模糊等)
- 11.Glide-图片的剪裁(ScaleType)
- 12.Glide-源码详解
前方高能预警,本文篇幅较长,阅读需要耐心
本文基于Glide 3.7.0版本
一.Glide的构造
//Glide.java
Glide(Engine engine, MemoryCache memoryCache, BitmapPool bitmapPool, Context context, DecodeFormat decodeFormat) {
...
}
Glide是通过GlideBuilder中的createGlide方法生成的(核心代码如下)
//GlideBuilder.java
Glide createGlide() {
...
return new Glide(engine, memoryCache, bitmapPool, context, decodeFormat);
}
Glide的构造参数主要有四个,都是通过createGlide生成的.
MemoryCache 内存缓存
BitmapPool 图片池
DecodeFormat 图片格式
Engine 引擎类
1.MemoryCache :内存缓存 LruResourceCache
//MemorySizeCalculator.java
final int maxSize = getMaxSize(activityManager);
private static int getMaxSize(ActivityManager activityManager) {
//每个进程可用的最大内存
final int memoryClassBytes = activityManager.getMemoryClass() * 1024 * 1024;
//判断是否低配手机
final boolean isLowMemoryDevice = isLowMemoryDevice(activityManager);
return Math.round(memoryClassBytes
* (isLowMemoryDevice ? LOW_MEMORY_MAX_SIZE_MULTIPLIER : MAX_SIZE_MULTIPLIER));
}
最大内存:如果是低配手机,就每个进程可用的最大内存乘以0.33,否则就每个进程可用的最大内存乘以0.4
//MemorySizeCalculator.java
int screenSize = screenDimensions.getWidthPixels() * screenDimensions.getHeightPixels()
* BYTES_PER_ARGB_8888_PIXEL;(宽*高*4)
int targetPoolSize = screenSize * BITMAP_POOL_TARGET_SCREENS;(宽*高*4*4)
int targetMemoryCacheSize = screenSize * MEMORY_CACHE_TARGET_SCREENS;(宽*高*4*2)
//判断是否超过最大值,否则就等比缩小
if (targetMemoryCacheSize + targetPoolSize <= maxSize) {
memoryCacheSize = targetMemoryCacheSize;
bitmapPoolSize = targetPoolSize;
} else {
int part = Math.round((float) maxSize / (BITMAP_POOL_TARGET_SCREENS + MEMORY_CACHE_TARGET_SCREENS));
memoryCacheSize = part * MEMORY_CACHE_TARGET_SCREENS;
bitmapPoolSize = part * BITMAP_POOL_TARGET_SCREENS;
}
targetPoolSize 和 targetMemoryCacheSize 之和不能超过maxSize 否则就等比缩小
//GlideBuilder.java
memoryCache = new LruResourceCache(calculator.getMemoryCacheSize());
内存缓存用的是targetMemoryCacheSize (即一般是缓存大小是屏幕的宽 * 高 * 4 * 2)
2.BitmapPool 图片池 LruBitmapPool
int size = calculator.getBitmapPoolSize();
bitmapPool = new LruBitmapPool(size);
图片池用的是targetPoolSize(即一般是缓存大小是屏幕的宽*高*4*4)
3.DecodeFormat 图片格式
DecodeFormat DEFAULT = PREFER_RGB_565
默认是RGB_565
4.Engine 引擎类
//GlideBuilder.java
engine = new Engine(memoryCache, diskCacheFactory, diskCacheService, sourceService);
engine 里面主要参数
- 内存缓存 memoryCache
- 本地缓存 diskCacheFactory
- 处理源资源的线程池 sourceService
- 处理本地缓存的线程池 diskCacheService
(1)memoryCache:内存缓存 LruBitmapPool
上面已经做了介绍
(2)diskCacheFactory:本地缓存 DiskLruCacheFactory
//DiskCache.java
/** 250 MB of cache. */
int DEFAULT_DISK_CACHE_SIZE = 250 * 1024 * 1024;
String DEFAULT_DISK_CACHE_DIR = "image_manager_disk_cache";
默认大小:250 MB
默认目录:image_manager_disk_cache
(3)sourceService 处理源资源的线程池 (ThreadPoolExecutor的子类)
final int cores = Math.max(1, Runtime.getRuntime().availableProcessors());//获得可用的处理器个数
sourceService = new FifoPriorityThreadPoolExecutor(cores);