Android 大批量图片显示时候如何避免OOM
来源:互联网 发布:淘宝苹果组装机 编辑:程序博客网 时间:2024/04/30 12:52
在开发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的初始化工作完成了。
主要实现获取图片的流程就是当需要获取图片时候,首先来从内存中获取缓存,如果获取到了就将图片显示到界面上。如果内存中没有获取到,则开启一个BitmapWorkerTask任务来去异步加载图片。
虽然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
- Android 大批量图片显示时候如何避免OOM
- 如何避免图片oom
- android如何避免oom
- Android 如何避免OOM
- 如何避免图片加载OOM
- Android显示图片避免OOM和ANR小结
- Android显示图片避免OOM和ANR小结
- Android显示图片避免OOM和ANR小结(转)
- Android显示图片避免OOM和ANR小结
- Android显示图片避免OOM和ANR小结
- android显示一张大的网络图片,避免OOM
- Android如何避免OOM总结
- Android如何避免OOM总结
- Android如何避免OOM总结
- Android如何避免OOM总结
- [Android]如何避免OOM异常
- Android如何避免OOM总结
- Android如何避免OOM总结
- 洛谷P1218 特殊的质数肋骨
- 斐波那契
- UICollectionView
- 字符串全排列算法学习总结
- 图片处理.md
- Android 大批量图片显示时候如何避免OOM
- Java JDBC基础
- flexigrid使用心得
- BZOJ 1008 [HNOI2008] 越狱
- Add Digits
- Vue随笔
- RemoveDuplicate from sorted ArrayII
- 代码很烂,所以离职?
- 搭建zookeeper集群