我有一个列表,显示从网络上下载的即时缩略图(小图像)。在某些情况下,进程会耗尽内存。如何判断空闲内存即将耗尽,以便停止下载更多图像?
我想提前知道,以免内存不足。
注意:这不是内存泄漏,只是下载了大量的位图。
谢谢。
发布于 2011-04-08 00:19:56
我使用SoftReference保存位图对象。该列表只需要当前可见的图像。因此,我永远不需要担心空间不足。
缺点是,当我看到图像时,向下滚动(导致一些SoftReferences清除位图),然后再次滚动回相同的位置-图像再次下载:(
而且,SoftReferences被清除的速度非常快。我希望他们保存内部位图的时间更长。
发布于 2011-09-13 05:39:27
1)你必须成为你自己的浏览器。
将拇指下载到SDCard中,而不是保存在内存中。在保存它们之前收缩/旋转它们,这样当您下一次需要加载它们时,从SDCard加载是“免费的”,而不是从internets昂贵。(即:像任何浏览器一样,使用本地文件缓存)。
释放为执行此操作而创建的任何临时Bitmap对象。
了解如何使用"inSampleSize“参数以低于原始分辨率的分辨率解压位图。
如果你写的文件以图像扩展名(.jpg等)结尾,它们将出现在图库中,所以不要用明显的图像文件名保存你的拇指。
2)创建分层缓存系统(位图> SDCard >互联网)。
解压缩略图时,将其保存在SoftReference缓存中。如果您需要使用该缩略图,请从缓存中请求它。如果VM需要更多内存,您的SoftReference实例可能会返回null。
如果你从你的位图缓存中得到了null,那么检查一下你是否已经把你的url放到了sd卡上,并从那里把它加载到了位图缓存中。
如果你从你的文件系统中得到了null,那么从互联网上下载图片并保存到SDCard中,然后把它放在你的位图缓存中。
3)释放未被使用的资源。
同样,请确保在视图离开屏幕时立即从放置它们的视图中清除位图(如果视图位于ListView或其他基于适配器的元素中,这本质上是“免费”的,无需回收视图元素) --但是,如果使用位图实例化了ImageViews,并且它们没有立即显示在屏幕上,则可能是在浪费堆。
您可以简单地在ImageView上调用setImageBitmap(null);,位图的引用将被删除(这样,如果唯一的引用是SoftReference,那么当它不被使用时)。
4)注意你所在的线程。
请记住,您必须从非UI线程下载位图(我们使用Service实例作为意图请求的队列),并且您必须仅在UI线程中将位图附加到View实例。
您需要创建一个良好的队列系统,以便将所有内容从UI线程加载到位图缓存中,然后使用处理程序告诉位图缓存填充UI线程上的ImageViews。
5)注意你的下载队列。
如果您和我们一样,同时拥有拇指和全尺寸图像,您需要手动使用优先级队列将您的图像请求放在thumb请求之前,或者使用两种不同的服务(将其不同的意图排入队列)来下载thumbs和full图像。
否则,您可能会排满拇指下载的整个屏幕,但直到所有拇指完成后,才会以完整的图像响应。
6)询问系统有多少内存。
Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo();
Debug.getMemoryInfo(memoryInfo);7) "onLowMemory()“没有做你期望的事情。
它适用于用户在手机上运行太多应用程序,操作系统需要从所有正在运行的应用程序中恢复物理内存的情况。
这与应用程序VM堆耗尽是完全不同的,因为加载太多位图很容易做到这一点。
据我所知,你不会得到警告,你只会崩溃(尽管你可以通过上面的调用跟踪内存信息)。
希望这有助于在互联网上下载和显示拇指时做出一些聪明的事情。
mig
发布于 2011-04-07 18:56:08
在创建位图时,应使用BitmapFactory.Options的inSampleSize选项。
此外,Android: out of memory exception in Gallery中的一些技巧对我保持对可用内存的检查很有用。
https://stackoverflow.com/questions/5579793
复制相似问题