Android进阶:Bitmap的高效加载和Cache,解析底层原理

Log.i(TAG, “initView: outWidth=”+outWidth+",outHeight="+outHeight);

//3、原始宽高信息 和 view的大小 计算并设置采样率

ViewGroup.LayoutParams layoutParams = ivBitamp.getLayoutParams();

int inSampleSize = getInSampleSize(layoutParams.width, layoutParams.height, outWidth, outHeight);

options.inSampleSize = inSampleSize;

Log.i(TAG, “initView: inSampleSize=”+options.inSampleSize);

//4、inJustDecodeBounds设为false,并加载图片

options.inJustDecodeBounds = false;

Bitmap bitmap= BitmapFactory.decodeResource(getResources(), R.mipmap.blue, options);

Log.i(TAG, “initView: size=”+bitmap.getByteCount());

int density = bitmap.getDensity();

Log.i(TAG, “initView: density=”+density);

Log.i(TAG, “initView: original size=”+3372224);

Log.i(TAG, “initView: calculated size=”+ (337/inSampleSize) (222/inSampleSize) density/480 *4);

//绘制到view

ivBitamp.setImageBitmap(bitmap);

}

/**

  • 计算采样率

  • @param width view的宽

  • @param height view的高

  • @param outWidth 图片原始的宽

  • @param outHeight 图片原始的高

  • @return

*/

private int getInSampleSize(int width, int height, int outWidth, int outHeight) {

int inSampleSize = 1;

if (outWidth>width || outHeight>height){

int halfWidth = outWidth / 2;

int halfHeight = outHeight / 2;

//保证采样后的宽高都不小于目标快高,否则会拉伸而模糊

while (halfWidth/inSampleSize >=width

&& halfHeight/inSampleSize>=height){

//采样率一般取2的指数

inSampleSize *=2;

}

}

return inSampleSize;

}

}

二、Android中的缓存策略

===============

缓存策略在Android中应用广泛。使用缓存可以节省流量、提高效率

加载图片时,一般会从网络加载,然后缓存在存储设备上,这样下次就不用请求网络了。并且通常也会缓存一份到内存中,这样下次可以直接取内存中的缓存,要比从存储设备中取快很多。所以一般是先从内存中取,内存没有就取存储设备,也没有才会请求网络,这就是所谓的“**三级

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

缓存**”。此策略同样适用其他文件类型。

缓存策略中的操作有 添加缓存、获取缓存、删除缓存。添加和获取比较好理解,删除缓存是啥意思?因为缓存大小是有限制的,像移动设备的 内存 和 设备存储都是有限的,不能无限制的添加,只能限定一个最大缓存,到达最大时就会删除一部分缓存。但是删除哪一部分缓存呢?删除 缓存创建时间最老的吗,如果它经常用到呢,好像不太完美,当然这也是一种缓存算法。

目前经典的缓存算法是LRU(Least Recently Used),最近最少使用。具体就是 当缓存满时,会先删除那些 近期 最少使用 的缓存。使用LRU算法的缓存有两种,LruCache和DiskLruCache,LruCache是使用内存缓存,DiskLruCache是实现磁盘缓存。

2.1 LruCache


LruCache是泛型类,使用方法如下: 提供最大缓存容量,创建LruCache实例,并重写其sizeOf方法来计算缓存对象的大小。最大容量和缓存对象大小单位要一致。

private void testLruCache() {

//当前进程的最大内存,单位M

long maxMemory = Runtime.getRuntime().maxMemory() / 1024 / 1024;

//取进程内存的1/8

int cacheMaxSize = (int) (maxMemory/8);

//创建Bitmap实例

mBitmapLruCache = new LruCache<String, Bitmap>(cacheMaxSize){

@Override

protected int sizeOf(String key, Bitmap value) {

//缓存对象bitmap的大小,单位M

return value.getByteCount()/1024/1024;

}

@Override

protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {

//移除旧缓存时会调用,可以在这里进行像资源回收的工作。

//evicted为true,表示此处移除是因为快满了要腾出空间

}

};

//添加缓存

mBitmapLruCache.put(“1”,mBitmap);

//获取缓存

Bitmap bitmap = mBitmapLruCache.get(“1”);

ivBitamp.setImageBitmap(bitmap);

//删除缓存,一般不会用,因为快满时会自动删近期最少使用的缓存,就是它的核心功能

mBitmapLruCache.remove(“1”);

}

可见使用很简单,那么LruCache是怎么完成 删除“近期最少使用” 的呢?看下LruCache的代码:

public class LruCache<K, V> {

//此map以强引用的方式存储缓存对象

private final LinkedHashMap<K, V> map;

//当前缓存的大小(带单位的)

private int size;

//缓存最大容量(带单位的)

private int maxSize;

public LruCache(int maxSize) {

if (maxSize <= 0) {

throw new IllegalArgumentException(“maxSize <= 0”);

}

this.maxSize = maxSize;

//LinkedHashMap是按照 访问顺序 排序的,所以get、put操作都会把要存的k-v放在队尾

this.map = new LinkedHashMap<K, V>(0, 0.75f, true);

}

/**

  • 获取缓存,同时会把此k-v放在链表的尾部

*/

public final V get(K key) {

i

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值