Android艺术——Bitmap高效加载和缓存代码分析

提兵百万西湖上,立马吴山第一峰!这篇文章主要讲述Android艺术——Bitmap高效加载和缓存代码分析相关的知识,希望能为你提供帮助。
Bitmap的加载与缓存代码分析:
图片的压缩
比如有一张1024*768像素的图像要被载入内存,然而最终你要用到的图片大小其实只有128*96,那么我们会浪费很大一部分内存,这显然是没有必要的,下面是一个实例:
public  static  int  calculateInSampleSize(   
                        BitmapFactory.Options  options,  int  reqWidth,  int  reqHeight)  {   
        //  Raw  height  and  width  of  image   
        final  int  height  =  options.outHeight;    
        final  int  width  =  options.outWidth;    
        int  inSampleSize  =  1;    
   
        if  (height  >   reqHeight  ||  width  >   reqWidth)  {   
   
                final  int  halfHeight  =  height  /  2;    
                final  int  halfWidth  =  width  /  2;    
   
                //  Calculate  the  largest  inSampleSize  value  that  is  a  power  of  2  and  keeps  both   
                //  height  and  width  larger  than  the  requested  height  and  width.   
                while  ((halfHeight  /  inSampleSize)  >   reqHeight   
                                & &   (halfWidth  /  inSampleSize)  >   reqWidth)  {   
                        inSampleSize  *=  2;    
                }   
        }   
   
        return  inSampleSize;    
}   
为了使用以上的方法,我们在裁剪之前,一定要记得使用inJustDecodeBounder来获取原图大小,在使用完之后,记得将inJustDecodeBounds置为false:
 
public  static  Bitmap  decodeSampledBitmapFromResource(Resources  res,  int  resId,   
                int  reqWidth,  int  reqHeight)  {   
   
        //  First  decode  with  inJustDecodeBounds=true  to  check  dimensions   
        final  BitmapFactory.Options  options  =  new  BitmapFactory.Options();    
        options.inJustDecodeBounds  =  true;    
        BitmapFactory.decodeResource(res,  resId,  options);    
   
        //  Calculate  inSampleSize   
      options.inSampleSize  =  calculateInSampleSize(options,  reqWidth,  reqHeight);    
   
        //  Decode  bitmap  with  inSampleSize  set   
        options.inJustDecodeBounds  =  false;    
        return  BitmapFactory.decodeResource(res,  resId,  options);    
}   
 
在剪裁工作做完后,我们就可以将位图载入ImageView了,比如我们设定期望大小为100*100:
 
mImageView.setImageBitmap(   
        decodeSampledBitmapFromResource(getResources(),  R.id.myimage,  100,  100));  
内存缓存技术
另外一种图片缓存的方式就是内存缓存技术。在android中,有一个叫做LruCache类专门用来做图片缓存处理的。
它有一个特点,当缓存的图片达到了预先设定的值的时候,那么近期使用次数最少的图片就会被回收掉。
步骤:(1)要先设置缓存图片的内存大小,我这里设置为手机内存的1/8,
手机内存的获取方式:int MAXMEMONRY = (int) (Runtime.getRuntime() .maxMemory() / 1024);
(2)LruCache里面的键值对分别是URL和对应的图片
(3)重写了一个叫做sizeOf的方法,返回的是图片数量。
private LruCache< String, Bitmap> mMemoryCache;
private LruCacheUtils() {
if (mMemoryCache == null)
mMemoryCache = new LruCache< String, Bitmap> (
MAXMEMONRY / 8) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// 重写此方法来衡量每张图片的大小,默认返回图片数量。
return bitmap.getRowBytes() * bitmap.getHeight() / 1024;
}
@Override
protected void entryRemoved(boolean evicted, String key,
Bitmap oldValue, Bitmap newValue) {
Log.v("tag", "hard cache is full , push to soft cache");

}
};
}
(4)下面的方法分别是清空缓存、添加图片到缓存、从缓存中取得图片、从缓存中移除。
移除和清除缓存是必须要做的事,因为图片缓存处理不当就会报内存溢出,所以一定要引起注意。
public void clearCache() {
if (mMemoryCache != null) {
if (mMemoryCache.size() > 0) {
Log.d("CacheUtils",
"mMemoryCache.size() " + mMemoryCache.size());
mMemoryCache.evictAll();
Log.d("CacheUtils", "mMemoryCache.size()" + mMemoryCache.size());
}
mMemoryCache = null;
}
}
public synchronized void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (mMemoryCache.get(key) == null) {
if (key != null & & bitmap != null)
mMemoryCache.put(key, bitmap);
} else
Log.w(TAG, "the res is aready exits");
}
public synchronized Bitmap getBitmapFromMemCache(String key) {
Bitmap bm = mMemoryCache.get(key);
if (key != null) {
return bm;
}
return null;
}
【Android艺术——Bitmap高效加载和缓存代码分析】/**
* 移除缓存
*
* @param key
*/
public synchronized void removeImageCache(String key) {
if (key != null) {
if (mMemoryCache != null) {
Bitmap bm = mMemoryCache.remove(key);
if (bm != null)
bm.recycle();
}
}
}
 


































































































    推荐阅读