Bitmap加载和Cache
- BitmapOptions
decodeFile
decodeStream
decodeResource
decodeByteArray
- BitmapFactory.Options
inSampleSize:采用率
为1时:采样后的图片和原图没区别
大于1:比如等于2时,采样后的图片宽高为原来的1/2,像素为原图的1/4,占用的内存大小也为原图的1/4
一张10241024的argb8888格式图片,每个像素大小是4bit(1bit8位,四个8就4bit),总大小为102410244=4MB,采用insamplesize为2后,总大小为512512*4=1MB
所以insampleSize大于1时才会有采样缩放
inSampleSize同时作用于宽高,宽高大小随采样率的2次方递减,1/采样率^2
inSampleSize小于1时值等于1来处理。
官方建议按照2的指数来设置inSampleSize,如1,2,4,16...
/*图片压缩采样*/
public Bitmap decodeSampledBitmapFromResource(Resources res, @IdRes int id, int reqWidth, int reqHeight) {
final BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, id, opts);
int outWidth = opts.outWidth;
int outHeight = opts.outHeight;
int inSampleSize = calculateInSampleSize(outWidth, outHeight, reqWidth, reqHeight);
opts.inJustDecodeBounds = false;
opts.inSampleSize = inSampleSize;
return BitmapFactory.decodeResource(res, id, opts);
}
private int calculateInSampleSize(int outWidth, int outHeight, int reqWidth, int reqHeight) {
if (reqHeight == 0 || reqWidth == 0) {
return 1;
}
int inSampleSize = 1;
if (outWidth > reqWidth || outHeight > reqHeight) {
int w = outWidth / 2;
int h = outHeight / 2;
while ((w / inSampleSize) >= reqWidth && (h / inSampleSize) >= reqHeight) {
inSampleSize *= 2;
}
}
Log.d(TAG, "inSampleSize:" + inSampleSize);
return inSampleSize;
}
- LruCache 内存缓存
- DisLruCache 存储设备缓存
-
LruCache
LruCache是一个泛型类,内部维护一个LinkedHashMap,以强引用的方式存储外界的对象,提供了get,put方法来完成缓存对象的获取和添加,当缓存满时,会移除较早使用的对象并添加新对象。
-
DiskLruCache
SDK源码中没有,需要去安卓开发者网站上下载
1. 创建:
public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
throws IOException {}
第四个参数maxSize表示总大小。当超过指定的总大小后,会通过lru算法删除某些内容。
2. 添加元素
通过edit()的Editor对象,如果这个缓存正在被编辑,edit()会返回null,建议对key进行MD5话,避免特殊字符的麻烦。
通过Editor.newOutputStream()获得输出流
通过Editor.commit()提交写入操作,通过Editor.abort()来回退整个操作,之后通过DiskLruCache.flush()刷新。
3. DiskLruCache缓存查找
通过get(key)方法,返回Snapshot对象,再通过Snapshot.getInputStream()获取输入流,加载文件。
- 优化列表卡顿
- getView中不做耗时操作
- 监听滚动事件,当滚动时不去加载图片,仅仅当列表停止时加载。
- 开启硬件加速:在Activity清单文件节点加上android:hardwareAccelerated="true"
网友评论