废话
每次从内存里面读图片,图片小的话还好,图片大的话比较吃力,速度慢不说,还容易因为内存问题出现崩溃。
后来加上了缓存,从缓存中读取,结果发现,还是会爆炸,检查一下发现,一张拍照3M多,直接把整个缓存区都炸开了,既然找到问题了,也就好解决了。
所以就加上了个压缩,逻辑是:1-从缓存中读取 2-读取不到,先从内存中读取,同时异步压缩图片 3-压缩完成之后写入缓存 4-再次读取可以在缓存中找到
工具
(缓存工具)Lrucache:https://blog.csdn.net/jxxfzgy/article/details/44885623
(图片压缩)鲁班压缩:https://github.com/Curzibn/Luban
代码
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.TextUtils;
import android.util.LruCache;
import java.io.File;
import top.zibin.luban.CompressionPredicate;
import top.zibin.luban.Luban;
import top.zibin.luban.OnCompressListener;
/**
* 图片缓存类(仅供缓存本地图片使用)
*/
public class LruCacheUtils {
private static LruCache<String, Bitmap> mMemoryCache;
/**
* 初始化(必须),推荐在Application中启动,一次就可以了
*/
public static void init() {
int maxMemory = (int) (Runtime.getRuntime().maxMemory());
// 使用最大可用内存值的1/8作为缓存的大小。
int cacheSize = maxMemory / 8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
protected int sizeOf(String key, Bitmap bitmap) {
//在每次存入缓存的时候调用
return bitmap.getByteCount() / 1024;
}
};
}
/**
* 将bitmap加入到缓存中
*
* @param path LruCache的键,即图片的下载路径
* @param bitmap LruCache的值,即图片的Bitmap对象
*/
public static void addImage(String path, Bitmap bitmap) {
if (mMemoryCache.get(path) == null) {
mMemoryCache.put(path, bitmap);
}
}
/**
* 读取缓存中的图片,不需要压缩
*
* @param path
* @return
*/
public static Bitmap getImage(String path) {
Bitmap bitmap = mMemoryCache.get(path);
if (bitmap != null) {
return bitmap;
}
bitmap = BitmapFactory.decodeFile(path);
if (bitmap != null) {
addImage(path, bitmap);
}
return bitmap;
}
/**
* 读取缓存中的图片,需要压缩
*
* @param path
* @return
*/
public static Bitmap getImage(Context context, final String path) {
Bitmap bitmap = mMemoryCache.get(path);
if (bitmap != null) {
//充缓存里面读取
return bitmap;
}
//缓存里面还没有
bitmap = BitmapFactory.decodeFile(path);//直接从文件中读取Bitmap出来
if (bitmap != null) {
String cachePath = PathUtils.getImgCache();//压缩之后的文件存放的文件夹,自己设置
Luban.with(context)
.load(path)
.ignoreBy(288)//不压缩的阈值,单位为K
.setTargetDir(cachePath)
.filter(new CompressionPredicate() {
@Override
public boolean apply(String path) {
return !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif"));
}
})
.setCompressListener(new OnCompressListener() {
@Override
public void onStart() {
// TODO 压缩开始前调用,可以在方法内启动 loading UI
}
@Override
public void onSuccess(File file) {
// TODO 压缩成功后调用,返回压缩后的图片文件
Bitmap bitmap1 = BitmapFactory.decodeFile(file.getPath());
// ALog.e("压缩成功:" + file.length());
addImage(path, bitmap1);
MyFileUtils.deleteFile(file);//已经缓存完成了,删除压缩好的文件
}
@Override
public void onError(Throwable e) {
// TODO 当压缩过程出现问题时调用
// ALog.e("压缩出错:" + e.toString());
addImage(path, BitmapFactory.decodeFile(path));//压缩失败,直接缓存(很少出现)
}
}).launch();
}
return bitmap;
}
}
调用:
Bitmap bitmap=LruCacheUtils.getImage(getContext(),path);