改进背景图片位图缓存方法。
This commit is contained in:
@@ -130,10 +130,11 @@ public class App extends GlobalApplication {
|
||||
public void onTerminate() {
|
||||
super.onTerminate();
|
||||
ToastUtils.release();
|
||||
// 可选:App 终止时清空 Bitmap 缓存,释放内存
|
||||
if (_mBitmapCacheUtils != null) {
|
||||
_mBitmapCacheUtils.clearAllCache();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrimMemory(int level) {
|
||||
super.onTrimMemory(level);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
package cc.winboll.studio.powerbell.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import cc.winboll.studio.powerbell.App;
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||
* @Date 2025/12/11 01:57
|
||||
* @Describe 单例 Bitmap 缓存工具类(Java 7 兼容)
|
||||
* 功能:内存缓存 Bitmap,支持路径关联缓存、全局获取、缓存清空
|
||||
* 特点:1. 单例模式 2. 压缩加载避免OOM 3. 路径- Bitmap 映射 4. 线程安全
|
||||
* 功能:内存缓存 Bitmap,支持路径关联缓存、全局获取、缓存清空、SP 持久化最后缓存路径、构造时预加载
|
||||
* 特点:1. 单例模式 2. 压缩加载避免OOM 3. 路径-Bitmap 映射 4. 线程安全 5. SP 持久化最后缓存路径 6. 构造时预加载
|
||||
*/
|
||||
public class BitmapCacheUtils {
|
||||
public static final String TAG = "BitmapCacheUtils";
|
||||
@@ -23,14 +24,24 @@ public class BitmapCacheUtils {
|
||||
private static final int MAX_WIDTH = 1080;
|
||||
private static final int MAX_HEIGHT = 1920;
|
||||
|
||||
// SP 相关常量
|
||||
private static final String SP_NAME = "BitmapCacheSP";
|
||||
private static final String SP_KEY_LAST_CACHE_PATH = "last_cache_image_path";
|
||||
|
||||
// 单例实例(volatile 保证多线程可见性)
|
||||
private static volatile BitmapCacheUtils sInstance;
|
||||
// 路径-Bitmap 缓存容器(内存缓存)
|
||||
private final Map<String, Bitmap> mBitmapCacheMap;
|
||||
// SP 实例(用于持久化最后缓存路径)
|
||||
private final SharedPreferences mSp;
|
||||
|
||||
// 私有构造器(单例模式)
|
||||
private BitmapCacheUtils() {
|
||||
mBitmapCacheMap = new HashMap<>();
|
||||
// 初始化 SP(使用 App 全局上下文,避免内存泄漏)
|
||||
mSp = App.getInstance().getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
|
||||
// 构造时自动预加载 SP 中保存的最后一次缓存路径的图片
|
||||
preloadLastCachedBitmap();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,7 +59,7 @@ public class BitmapCacheUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* 核心接口:根据图片路径缓存 Bitmap 到内存
|
||||
* 核心接口:根据图片路径缓存 Bitmap 到内存,并持久化路径到 SP
|
||||
* @param imagePath 图片绝对路径
|
||||
* @return 缓存成功的 Bitmap / null(路径无效/文件不存在/解码失败)
|
||||
*/
|
||||
@@ -70,6 +81,8 @@ public class BitmapCacheUtils {
|
||||
// 额外校验缓存的Bitmap是否有效
|
||||
if (cachedBitmap != null && !cachedBitmap.isRecycled()) {
|
||||
LogUtils.d(TAG, "cacheBitmap: 图片已缓存,直接返回 - " + imagePath);
|
||||
// 持久化当前路径到 SP(更新最后缓存路径)
|
||||
saveLastCachePathToSp(imagePath);
|
||||
return cachedBitmap;
|
||||
} else {
|
||||
// 缓存的Bitmap已失效,移除后重新加载
|
||||
@@ -83,7 +96,9 @@ public class BitmapCacheUtils {
|
||||
if (bitmap != null) {
|
||||
// 存入缓存容器
|
||||
mBitmapCacheMap.put(imagePath, bitmap);
|
||||
LogUtils.d(TAG, "cacheBitmap: 图片缓存成功 - " + imagePath);
|
||||
// 持久化当前路径到 SP(更新最后缓存路径)
|
||||
saveLastCachePathToSp(imagePath);
|
||||
LogUtils.d(TAG, "cacheBitmap: 图片缓存成功并持久化路径 - " + imagePath);
|
||||
} else {
|
||||
LogUtils.e(TAG, "cacheBitmap: 图片解码失败 - " + imagePath);
|
||||
}
|
||||
@@ -109,7 +124,7 @@ public class BitmapCacheUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空所有 Bitmap 缓存(释放内存)
|
||||
* 清空所有 Bitmap 缓存(释放内存),并清空 SP 中保存的最后缓存路径
|
||||
*/
|
||||
public void clearAllCache() {
|
||||
synchronized (mBitmapCacheMap) {
|
||||
@@ -120,7 +135,9 @@ public class BitmapCacheUtils {
|
||||
}
|
||||
mBitmapCacheMap.clear();
|
||||
}
|
||||
LogUtils.d(TAG, "clearAllCache: 所有 Bitmap 缓存已清空");
|
||||
// 清空 SP 中保存的最后缓存路径
|
||||
clearLastCachePathInSp();
|
||||
LogUtils.d(TAG, "clearAllCache: 所有 Bitmap 缓存已清空,SP 路径已清除");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,6 +154,12 @@ public class BitmapCacheUtils {
|
||||
bitmap.recycle();
|
||||
LogUtils.d(TAG, "removeCachedBitmap: 移除并回收缓存 - " + imagePath);
|
||||
}
|
||||
// 若移除的是最后缓存的路径,清空 SP
|
||||
String lastPath = getLastCachePathFromSp();
|
||||
if (imagePath.equals(lastPath)) {
|
||||
clearLastCachePathInSp();
|
||||
LogUtils.d(TAG, "removeCachedBitmap: 移除的是最后缓存路径,已清空 SP");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,5 +225,53 @@ public class BitmapCacheUtils {
|
||||
}
|
||||
return inSampleSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 SP 中获取最后一次缓存的图片路径
|
||||
* @return 最后缓存的路径 / null(未保存)
|
||||
*/
|
||||
private String getLastCachePathFromSp() {
|
||||
return mSp.getString(SP_KEY_LAST_CACHE_PATH, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将当前缓存路径持久化到 SP
|
||||
* @param imagePath 图片绝对路径
|
||||
*/
|
||||
private void saveLastCachePathToSp(String imagePath) {
|
||||
if (TextUtils.isEmpty(imagePath)) {
|
||||
return;
|
||||
}
|
||||
mSp.edit().putString(SP_KEY_LAST_CACHE_PATH, imagePath).commit(); // Java 7 兼容,使用 commit 而非 apply
|
||||
LogUtils.d(TAG, "saveLastCachePathToSp: 持久化最后缓存路径 - " + imagePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空 SP 中保存的最后缓存路径
|
||||
*/
|
||||
private void clearLastCachePathInSp() {
|
||||
mSp.edit().remove(SP_KEY_LAST_CACHE_PATH).commit();
|
||||
LogUtils.d(TAG, "clearLastCachePathInSp: SP 中最后缓存路径已清空");
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造时预加载 SP 中保存的最后一次缓存路径的图片
|
||||
*/
|
||||
private void preloadLastCachedBitmap() {
|
||||
String lastPath = getLastCachePathFromSp();
|
||||
if (TextUtils.isEmpty(lastPath)) {
|
||||
LogUtils.d(TAG, "preloadLastCachedBitmap: SP 中无保存的缓存路径,跳过预加载");
|
||||
return;
|
||||
}
|
||||
// 调用 cacheBitmap 预加载(内部已做文件校验和缓存判断)
|
||||
Bitmap bitmap = cacheBitmap(lastPath);
|
||||
if (bitmap != null) {
|
||||
LogUtils.d(TAG, "preloadLastCachedBitmap: 预加载 SP 中最后缓存路径成功 - " + lastPath);
|
||||
} else {
|
||||
LogUtils.w(TAG, "preloadLastCachedBitmap: 预加载 SP 中最后缓存路径失败,清空无效路径 - " + lastPath);
|
||||
// 预加载失败,清空 SP 中无效路径
|
||||
clearLastCachePathInSp();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user