使用 LruCache 来缓存图片来防止OOM

来源:互联网 发布:办公软件表格 编辑:程序博客网 时间:2024/04/28 16:57

如下是一个LruCache 来缓存图片的例子:

private LruCache<String, Bitmap> mMemoryCache;   @Override  protected void onCreate(Bundle savedInstanceState) {    // 获取到可用内存的最大值,使用内存超出这个值会引起OutOfMemory异常。   // LruCache通过构造函数传入缓存值,以KB为单位。     int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);     // 使用最大可用内存值的1/8作为缓存的大小。      int cacheSize = maxMemory / 8;     mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {         @Override          protected int sizeOf(String key, Bitmap bitmap) {      // 重写此方法来衡量每张图片的大小,默认返回图片数量             return bitmap.getByteCount() / 1024;         }     };  }  public void addBitmapToMemoryCache(String key, Bitmap bitmap) {     if (getBitmapFromMemCache(key) == null) {          mMemoryCache.put(key, bitmap);      }  }  public Bitmap getBitmapFromMemCache(String key) {      return mMemoryCache.get(key);  }  

在这个例子当中,使用了系统分配给应用程序的八分之一内存来作为缓存大小。在中高配置的手机当中,这大概会有4兆(32/8)的缓存空间。一个全屏幕的 GridView 使用4张 800x480分辨率的图片来填充,则大概会占用1.5兆的空间(800*480*4)。因此,这个缓存大小可以存储2.5页的图片。
当向 ImageView 中加载一张图片时,首先会在 LruCache 的缓存中进行检查。如果找到了相应的键值,则会立刻更新ImageView ,否则开启一个后台线程来加载这张图片。

public void loadBitmap(int resId, ImageView imageView) {    final String imageKey = String.valueOf(resId);      final Bitmap bitmap = getBitmapFromMemCache(imageKey);     if (bitmap != null) {         imageView.setImageBitmap(bitmap);     } else {         imageView.setImageResource(R.drawable.image_placeholder);         BitmapWorkerTask task = new BitmapWorkerTask(imageView);        task.execute(resId);     }  }  

BitmapWorkerTask 还要把新加载的图片的键值对放到缓存中。

class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {      // 在后台加载图片。      @Override     protected Bitmap doInBackground(Integer... params) {        final Bitmap bitmap = decodeSampledBitmapFromResource(                  getResources(), params[0], 100, 100);         addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);          return bitmap;     }  }  
0 0
原创粉丝点击