Bitmap

缓存

策略:二级缓存

  • LruCache 内存缓存 内部采用LinkdedHashMap强引用
  • DiskLruCache 硬盘缓存 以空间换时间

OOM

  • 原因
    图片分辨率过大 导致加载图片所需内存超过系统分配给进程的运行内存

  • 解决方案
    BitmapFactory OptionsinSampleSize计算合适的分辨率

计算合适的inSampleSize

public static int calculateInSampleSize(BitmapFactory.Options options,  
          int reqWidth, int reqHeight) {  
      // 源图片的高度和宽度  
      final int height = options.outHeight;  
      final int width = options.outWidth;  
      int inSampleSize = 1;  
      if (height > reqHeight || width > reqWidth) {  
          // 计算出实际宽高和目标宽高的比率  
          final int heightRatio = Math.round((float) height / (float) reqHeight);  
          final int widthRatio = Math.round((float) width / (float) reqWidth);  
          // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高  
          // 一定都会大于等于目标的宽和高。  
          inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;  
      }  
      return inSampleSize;  
  }
    

根据inSampleSize压缩图片:

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,int reqWidth, int reqHeight) {  
    // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小  
    final BitmapFactory.Options options = new BitmapFactory.Options();  
    options.inJustDecodeBounds = true;  
    BitmapFactory.decodeResource(res, resId, options);  
    // 调用上面定义的方法计算inSampleSize值  
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);  
    // 使用获取到的inSampleSize值再次解析图片  
    options.inJustDecodeBounds = false;  
    return BitmapFactory.decodeResource(res, resId, options);  
} 

LruCache

  • 线程安全
  • 初始化过程
int maxMemory = (int)(Runtime.getRuntime().maxMemory()/1024); //单位kb
int cacheSize = maxMemory / 8;
mMemoryCache = new LruCache(cacheSize){
    protected int sizeOf(String key, Bitmap bitmap){
        return bitmap.gteRowBytes() * bitmap.getHeight() / 1024;
    }
}

你可能感兴趣的:(Bitmap)