使用缓存来提高在Android的ListView与图片滚动性能 [英] Using caching to improve scrolling performance in an android ListView with images

查看:101
本文介绍了使用缓存来提高在Android的ListView与图片滚动性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前使用一个文件系统缓存,因为我从服务器下载到缓存我的图片。我有一个ListView包含自定义视图,每个从什么时候getView()被调用的文件系统中检索自己的形象。

I'm currently using a filesystem cache to cache my images as I download them from the server. I have a ListView that contains custom views, each of which retrieves its image from the filesystem when getView() is called.

要提高性能,我实现了一个 java.util.WeakHashMap中的<字符串,位图> ,每一个位图的存储通过一个唯一的密钥。这使我的图像掖进HashMap的,因为它们可以下载,然后直接从内存中检索它们来填充我的列表视图。这样就避免了在一个更流畅的滚动体验一个文件I / O操作和结果。

To improve performance, I implemented a java.util.WeakHashMap<String,Bitmap> that stores each of the bitmaps by a unique key. This allows me to tuck the images into the hashmap as they're downloaded, and then retrieve them directly from memory to populate my listview. This avoids a file I/O operation and results in a much smoother scrolling experience.

我们的想法是,作为OS上运行内存不足,将清理出的WeakHashMap以释放内存。

The idea is that as the OS runs low on memory, it will clean out the WeakHashMap to free up memory.

不过,这并没有在Android 2.3或更早版本的工作。的问题是,位图不保持在Java堆,并代替保存在本机存储器中。这意味着,在JVM垃圾收集器已经不知道多少内存的图像占用,因此从来没有困扰释放它们时,操作系统是低的本机内存,导致内存溢出错误时,有足够的内存仍然可以回收。

However, this doesn't work on Android 2.3 or earlier. The problem is that bitmaps are not kept in the Java Heap, and are instead kept in native memory. This means that the JVM garbage collector has no idea how much memory those images are occupying, and thus never bothers to free them up when the OS is low on native memory, resulting in OutOfMemory errors when there's plenty of memory that can still be reclaimed.

这已得到修复的Andr​​oid 3.0,因为3.0的位图存储在JVM堆,而不是本机内存,但问题是我怎么能轻松地在Android 2.3的位图缓存,后来没有在不经意间造成不必要的内存溢出的异常?

This has been fixed in Android 3.0, since 3.0 stores bitmaps in JVM heap instead of native memory, but the question is how can I easily cache bitmaps on Android 2.3 and later without inadvertently causing unnecessary OutOfMemory exceptions?

推荐答案

因此​​,答案似乎是有一个错误的方式在Dalvik时,它需要做GC通虚拟机检测。如果你手动调用的System.gc()立即为你的位图分配内存之前,该内存溢出错误,令人惊讶的走了。

So the answer seems to be that there's a bug in the way the dalvik VM detects when it needs to do a GC pass. If you manually call System.gc() immediately before allocating memory for your bitmap, the OutOfMemory errors surprisingly go away.

    if(Build.VERSION.SDK_INT < 12) {
        Log.d("Running garbage collection for Bitmaps");
        System.gc();
    }
    return BitmapFactory.decodeStream(is);

显然,虚拟机应该自动做这个GC它抛出一个内存溢出之前,但它似乎并没有这样做。

Obviously, the VM should be doing this GC automatically before it throws an OutOfMemory, but it does not appear to do so.

这篇关于使用缓存来提高在Android的ListView与图片滚动性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆