Android 大批量图片显示时候如何避免OOM

     在开发Android数据恢复应用的时候,最蛋疼的莫过于图片恢复部分,大批量的图片加载,在浏览的过程很容易就出现崩溃, 而这个异常就是OutOfMemory的错误,简称为OOM。(烦)     Android 的虚拟机是基于寄存器的Dalvik,它的最大堆大小一般是16M,有的机器为24M。我们平常看到的OutOfMemory的错误,通常 是堆内存溢出。移动开发和web开发的最大的区别是设备资源受限,对一般手机应用,这个资源是相当有限的,堆内存的上限值只有16M。Android的缺 省值是16M(某些机型是24M),而对于普通应用这是不能改的,当应用程序处理大资源的资源,如图片或视频等媒体资源时 ,数量一多,时间一长,这个16M是很容易耗尽的,OOM是很容易出现的。
      虽然JAVA有垃圾回收机制,但也存在内存泄露。如果我们一个程序中,已经不再使用某个对象,但是因为仍然有引用指向它,垃圾回收器就无法回收它,当然 该对象占用的内存就无法被使用,这就造成了内存泄露。如果我们的java运行很久,而这种内存泄露不断的发生,最后就没内存可用了。当然java的,内存 泄漏和C/C++是不一样的。如果java程序完全结束后,它所有的对象就都不可达了,系统就可以对他们进行垃圾回收,它的内存泄露仅仅限于它本身,而不 会影响整个系统的。C/C++的内存泄露就比较糟糕了,它的内存泄露是系统级,即使该C/C++程序退出,它的泄露的内存也无法被系统回收,永远不可用 了,除非重启机器。

    幸好的是在网上找不到不少针对大批量图片加载的优化方案,完美解决的主要方案还是LruCache和DiskLruCache完美结合到一起其实这个方案主要就是通过硬盘缓存和内存缓存的合作来完成,因为单靠内存来缓存这么多的图片显然是不显示的,但是单靠硬盘缓存,在读取方面又不如内存缓存获取的速度快。因为两者结合就可以很好解决

   

int maxMemory = (int) Runtime.getRuntime().maxMemory();  
  int cacheSize = maxMemory / 8;  
  mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {  
@Override  
  protected int sizeOf(String key, Bitmap bitmap) {  
     return bitmap.getByteCount();  
  };  
try {  
    File cacheDir = getDiskCacheDir(context, "thumb");  
    if (!cacheDir.exists()) {  
        cacheDir.mkdirs();  
    }  
    // 创建DiskLruCache实例,初始化缓存数据  
    mDiskLruCache = DiskLruCache  
            .open(cacheDir, getAppVersion(context), 1, 10 * 1024 * 1024);  
} catch (IOException e) {  
    e.printStackTrace();  
}

这部分代码就是完成把LruCache和DiskLruCache的初始化工作完成了。
主要实现获取图片的流程就是当需要获取图片时候,首先 来从内存中获取缓存,如果获取到了就将图片显示到界面上。如果内存中没有获取到,则开启一个BitmapWorkerTask任务来去异步加载图片。

那么在BitmapWorkerTask的doInBackground()方法中,主要用使用DiskLruCache技术。首先根据图片的URL生成对应的MD5 key,然后调用DiskLruCache的get()方法来获取硬盘缓存,如果没有获取到的话则从网络上请求图片并写入硬盘缓存,接着将Bitmap对象解析出来并添加到内存缓存当中,最后将这个Bitmap对象显示到界面上,这样一个完整的流程就执行完了。

DiskLruCache会根据我们在调用open()方法时设定的缓存最大值来自动删除多余的缓存。只有你确定某个key对应的缓存内容已经过期,需要从网络获取最新数据的时候才应该调用remove()方法来移除缓存。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值