12_Bitmap的加载和Cache

Bitmap的加载和Cache

1、Bitmap的高效加载

如何有效地加载一个Bitmap,这是一个很有意义的话题,由于Bitmap的特殊性以及Android对单个应用说施加的内存限制,比如早起的16M,这导致加载Bitmap的时候很容易出现内存溢出。

Bitmap在Android中指的是一张图片,可以是png格式也可以是jpg等其他常见的图片格式。可以通过BitmapFactory类提供的四类方法:decodeFile、decodeResource、decodeStream、decodeByteArray,分别用于加载文件系统、资源、输入流和字节数组中加载一个Bitmap对象。

如何高效地加载Bitmap呢?

核心思想是:采用BitmapFactory.options来加载所需尺寸的图片。通过BitmapFactory.Options就可以按一定的采样率来加载缩小后的图片,将缩小后的图片在ImageView中显示,这样就会降低内存占用从而在一定程度上避免OOM,提高了Bitmap加载时的性能。通过BitmapFactory.Options来缩放图片,主要是用到了它的insampleSize参数,即采样率。

但inSampleSize为1时,采样后的图片大小为原始的大小。当为2时,采样后的图片宽高均为原图大小的1/2,而像素是原图的1/4。Bitmap的大小=宽*高*BitmapConfig。

ARGB8888:一个像素占4字节

ARGB4444:一个像素占2字节

RGB_565:一个像素2字节,没有透明度

ALPHA_8:一个像素字节,只有透明度

如何获取采样率?

①、将BitmapFactory.Options的inJusticeDecodeBounds参数设为true并加载图片

②、从BitmapFactory.Options中取出图片的原始宽高信息,它们对应于outWidth和outHeight参数

③、根据采样率的规则并结合目标View的所需大小计算出采样率inSampleSize

④、将BitmapFactory.Options的inJustDecodeBounds参数设为false,然后重新加载图片

代码示例:

  public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        calulateInSampleSize(options, reqWidth, reqHeight);
        return BitmapFactory.decodeResource(res, resId, options);
    }

    public static int calulateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        int height = options.outHeight;
        int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }

2、Android中的缓存策略

缓存策略是一个通用对的思想,可以用在很多场景中,但是实际开发中经常需要用Bitmap做缓存。通过缓存,我们不需要每次都从网络上请求图片或者从存储设备中加载图片,这样极大地提高了图片的加载效率以及产品的用户体验。

目前比较常用的缓存策略是LruCache和DiskLruCache,其中LruCache常被用作内存缓存,而DiskLruCache常被用作存储缓存。Lru是Least Recently Used的缩写,即最近最少使用算法,这种算法的核心思想是:当缓存快满时,会淘汰近期最少使用的缓存目标,很显然Lru算法的思想是很容易被接受的。

程序第一次从网络加载图片后,就将其缓存到存储设备上,这样下次使用这张图片就不用再从网络上获取了,这样就为用户节省了流量。很多时候为了提高应用的用户体验,往往还会把图片在内存中再缓存一份,这样当应用打算从网络上请求一张图片时,程序会首先从内存中获取,如果内存中没有那么就从存储设备中去获取,如果存储设备中也没有,那就从网络上下载这张图片。

目前常用的一种缓存算法是LRU(Least Recently Used),LRU是近期最少使用算法,它的核心思想是当缓存满时,会优先淘汰那些近期最少使用的缓存对象。

采用LRU算法的缓存有两种:LruCache和DiskLruCache,LruCache用于实现内存缓存,而DiskLruCache这充当了存储设备缓存,通过这两者的结合,就可以实现一个高实用的ImageLoader。

1)LruCache,是Android 3.1所提供的一个缓存类,是一个泛型类,它内部采用一个LinkedHashMap以强引用的方式存储外界的缓存对象,其提供了get和put方法来完成缓存的获取和添加操作,当缓存满时,LruCache会移除较早使用的缓存对象,然后再添加新的缓存对象。

强引用:直接的对象引用

软引用:当一个对象只有软引用存在时,系统内存不足时此对象会被gc回收

弱引用:当一个对象只有弱引用存在时,此对象会随时被gc回收

2)DiskLruCache:DiskUrlCache用于实现存储设备缓存,它通过将缓存对象写入文件系统从而实现缓存的效果。

3、ImageLoader的使用

优秀的第三方图片加载框架:Android-Universal-Image-Loaderglidepicassofresco

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值