IT评测·应用市场-qidao123.com
标题:
面试总结之 Glide自定义的三级缓存策略
[打印本页]
作者:
圆咕噜咕噜
时间:
2025-3-20 04:53
标题:
面试总结之 Glide自定义的三级缓存策略
一、为什么需要三级缓存?
在移动应用开发中,图片加载性能直接影响用户体验。根据 Google 统计,图片加载延迟超过 1 秒会导致 32% 的用户流失。传统图片加载方案存在以下痛点:
内存占用高:未压缩的大图直接占用大量内存
重复下载:相同图片多次从网络获取
弱网体验差:离线场景无法加载图片
Glide 通过三级缓存策略,将图片加载速度提升 50%,内存占用降低 45%
内存缓存(Memory Cache)
import android.content.Context;
import com.bumptech.glide.Glide;
import com.bumptech.glide.GlideBuilder;
import com.bumptech.glide.load.engine.cache.LruResourceCache;
import com.bumptech.glide.module.AppGlideModule;
public class CustomGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
// 获取设备的最大内存
int maxMemory = (int) Runtime.getRuntime().maxMemory();
// 计算内存缓存的大小,这里设置为最大内存的15%
int memoryCacheSize = maxMemory / 1024 / 1024 * 15;
// 创建LruResourceCache对象
builder.setMemoryCache(new LruResourceCache(memoryCacheSize));
}
}
复制代码
解释:我们自定义了一个 AppGlideModule 类 CustomGlideModule。在 applyOptions 方法里,先获取设备的最大内存,接着盘算出内存缓存的巨细,这里设定为最大内存的 15%,末了使用 LruResourceCache 来设置内存缓存。
LruCache 实现:最大缓存容量为应用内存的 15%
缓存键生成策略:包含 URL + 宽高 + 格式的复合键
内存泄漏防护:通过 Glide 生命周期绑定
磁盘缓存(Disk Cache)
import android.content.Context;
import com.bumptech.glide.Glide;
import com.bumptech.glide.GlideBuilder;
import com.bumptech.glide.load.engine.cache.DiskLruCacheFactory;
import com.bumptech.glide.module.AppGlideModule;
public class CustomDiskCacheGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
// 设置磁盘缓存的路径
String diskCachePath = context.getCacheDir().getPath() + "/glide_cache";
// 设置磁盘缓存的大小为100MB
int diskCacheSize = 1024 * 1024 * 100;
// 创建DiskLruCacheFactory对象
builder.setDiskCache(new DiskLruCacheFactory(diskCachePath, diskCacheSize));
}
}
复制代码
解释:我们同样自定义了一个 AppGlideModule 类 CustomDiskCacheGlideModule。在 applyOptions 方法里,先设置磁盘缓存的路径,再将磁盘缓存的巨细设置为 100MB,末了使用 DiskLruCacheFactory 来设置磁盘缓存。
磁盘缓存目录:应用专属缓存目录
缓存镌汰算法:LRU 策略
缓存数据格式:使用 Glide 的默认序列化方式
网络缓存(Network Cache)
import android.content.Context;
import com.bumptech.glide.Glide;
import com.bumptech.glide.GlideBuilder;
import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.module.AppGlideModule;
import okhttp3.Cache;
import okhttp3.OkHttpClient;
import java.io.InputStream;
public class CustomNetworkCacheGlideModule extends AppGlideModule {
@Override
public void registerComponents(Context context, Glide glide, Registry registry) {
// 设置网络缓存的路径
Cache cache = new Cache(context.getCacheDir(), 1024 * 1024 * 50);
// 创建OkHttpClient对象并设置缓存
OkHttpClient client = new OkHttpClient.Builder()
.cache(cache)
.build();
// 注册OkHttpUrlLoader,让Glide使用OkHttp进行网络请求
registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(client));
}
}
复制代码
解释:自定义了 CustomNetworkCacheGlideModule 类,在 registerComponents 方法中,先设置网络缓存的路径和巨细(这里是 50MB),然后创建 OkHttpClient 并设置缓存,末了注册 OkHttpUrlLoader,使 Glide 接纳 OkHttp 举行网络哀求。
结合 OkHttp 实现 HTTP 缓存
缓存控制策略:根据响应头的 Cache-Control 字段
网络哀求重试机制:3 次重试 + 指数退避
使用 Glide 加载图片
import android.os.Bundle;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView imageView = findViewById(R.id.imageView);
String imageUrl = "https://example.com/image.jpg";
Glide.with(this)
.load(imageUrl)
// 设置磁盘缓存策略为缓存所有类型的图片
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
}
}
复制代码
在 MainActivity 中,我们使用 Glide 加载图片。通过 diskCacheStrategy(DiskCacheStrategy.ALL) 方法设置磁盘缓存策略,这里表现缓存全部类型的图片。
简朴概述:
内存缓存
(手机内存)
存近来看过的图,像手机相册近来项目
优化:只存 15% 内存空间,主动清算不常用的
磁盘缓存
(手机硬盘)
存常用图的备份,像电脑硬盘
优化:存 100MB,优先存高质量图
网络缓存
(路由器缓存)
存已经下载过的图,像小区快递柜
优化:存 50MB,制止重复下载
具体概述
每一层的具体实现
1.
内存缓存
(Memory Cache)
作用
:快速表现刚看过的图片(如滑动列表时往返切换的图片)
实现
:
使用 LruCache 算法(近来最少使用),主动清算长时间不消的图片
限制:只占手机可用内存的 15%(比方手机有 8GB 内存,内存缓存约 1.2GB)
优化
:
图片按屏幕尺寸压缩(比如原图 2000px,手机屏幕 1000px,只存 1000px 版本)
主动清算超出内存限制的图片
2.
磁盘缓存
(Disk Cache)
作用
:存常用但临时不在内存中的图片(如用户常常访问的商品详情页图片)
实现
:
使用 DiskLruCache 存储在手机硬盘
限制:总容量 100MB,优先存高质量图片
优化
:
按 URL 哈希值命名文件,制止重复存储相同图片
主动清算超过 7 天未使用的图片
3.
网络缓存
(Network Cache)
作用
:制止重复从服务器下载相同图片(需结合 HTTP 缓存头)
实现
:
通过 OkHttp 的缓存机制,将图片存在路由器或基站缓存中
限制:总容量 50MB,优先存高频访问的图片
优化
:
根据 HTTP 的Cache-Control头设置缓存时间(如设置为 1 天)
图片 URL 带版本号(如image_v2.jpg),版本更新时强制重新下载
常见问题解决方案
1. 缓存穿透
Glide.with(context)
.load(url)
.error(R.drawable.ic_error) // 设置错误占位图
.placeholder(R.drawable.ic_loading) // 设置加载占位图
.fallback(R.drawable.ic_fallback) // 设置空值占位图
.into(imageView);
复制代码
2. 缓存雪崩
int cacheDuration = TimeUnit.HOURS.toMillis(24) + new Random().nextInt(3600000);
复制代码
3. OOM 预防
// 使用RGB_565格式减少内存占用
Glide.with(context)
.load(url)
.format(DecodeFormat.PREFER_RGB_565)
.into(imageView);
复制代码
关键指标的获取途径
冷启动加载时间
工具运用
:借助 Android Profiler 的 Timeline 功能来精准测量。
操作办法
:在应用启动时,启动 Profiler 并纪录图片加载所耗费的时长。
代码示例
:
long startTime = System.currentTimeMillis();
Glide.with(this).load(url).into(imageView);
long duration = System.currentTimeMillis() - startTime;
Log.d("GlideTest", "加载耗时: " + duration + "ms");
复制代码
内存峰值占用情况
工具选择
:使用 Android Profiler 的 Memory Monitor 举行监测。
操作步调
:在滑动列表时,留意 Heap Size 的变革趋势。
优化要点
:对比开启缓存前后,Bitmap 内存占用的差异。
缓存命中率盘算
工具利用
:通过 Glide 的日志输出(设置Glide.get(context).setLogLevel(Log.DEBUG))。
数据提取
:从日志中筛选出Fetched和Decoded相关的条目。
盘算公式
:缓存命中率 = (内存命中数 + 磁盘命中数)÷ 总哀求数 × 100%。
FPS 帧率监控
工具使用
:接纳 Android Profiler 的 FrameMetrics 功能。
操作方式
:在滑动列表的过程中,纪录丢帧的数目。
优化目标
:确保平均帧率稳固在 55fps 以上。
扩展追问:
如何解决内存缓存导致的 OOM 问题?
动态尺寸压缩:
Glide.with(context)
.load(url)
.override(imageView.width, imageView.height)
.into(imageView)
复制代码
格式优化:优先使用 WebP 格式(体积减少 30%)
生命周期绑定:通过Glide.with(this)主动开释资源
内存监控:结合 Android Profiler 设置内存阈值报警
总结:通过合理设置和优化,可显著提升应用性能,降低用户流失率。建议开发者在新项目中优先接纳 Glide 的三级缓存方案,并根据现实需求举行定制化调解。
感谢观看!!!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/)
Powered by Discuz! X3.4