Android内存预防

Ali*_*aka 9 memory android bitmap download out-of-memory

我有一个列表,显示从网上即时下载的缩略图(小图像).在某些时候,该过程耗尽内存.我如何判断可用内存即将耗尽,以便我可以停止下载更多图像?

我想提前知道它,以免陷入内存不足的边缘.

注意:这不是内存泄漏,只是大量下载的位图.

谢谢.

mig*_*mig 27

1)您必须是自己的浏览器.

将您的拇指下载到SD卡而不是将它们保存在RAM中.在保存它们之前收缩/旋转它们,这样当您下次需要加载它们时,负载从SDCard"免费"而不是互联网的昂贵.(即:像任何浏览器一样,使用本地文件缓存).

释放您可能创建的任何临时Bitmap对象以执行此操作.

了解如何使用" inSampleSize"参数以低于原始分辨率的方式解压缩位图.

如果您编写的文件以图像扩展名(.jpg等)结尾,则它们将显示在图库中,因此请勿使用明显的图像文件名保存您的拇指.

2)创建分层缓存系统(位图> SD卡>互联网).

解压缩缩略图时,请将其保存在SoftReference缓存中.如果您需要使用该缩略图,请从缓存中请求它.如果VM需要更多内存,则SoftReference实例可能返回null.

如果从位图缓存中获取null,请检查您是否已将您的URL放在SD卡上并从那里将其加载到位图缓存中.

如果从文件系统中获取null,则从Internet下载映像并将其保存到SDCard并将其粘贴到位图缓存中.

3)释放未使用的资源.

以同样的方式,一旦View在屏幕外,请确保从它们放置的视图中清除位图(如果您的视图存在于ListView或其他基于Adapter的元素中,这实际上是"免费"回收查看元素) - 但是,如果您使用Bitmaps实例化ImageView,并且它们不会立即显示在屏幕上,那么您可能会浪费堆.

您可以简单地调用setImageBitmap(null);ImageView,并且将删除对Bitmap的引用(因此,如果唯一的ref是未使用时的SoftReference).

4)注意你所处的线程.

请记住,您必须从非UI线程下载位图(我们使用Service实例作为意图请求的队列),并且您必须仅在UI线程中将位图附加到View实例.

您需要创建一个良好的排队系统,将所有内容加载到UI线程的位图缓存中,然后使用Handler告诉您的位图缓存在UI线程上填充ImageViews.

5)注意你的下载队列.

如果你像我们一样,你有拇指全尺寸图像,你需要手动使用优先级队列在你的拇指请求之前放置你的图像请求,或者使用两个不同的服务(排队他们各自的意图)来下载大拇指vs完整的图像.

否则,您可能会排队一个充满拇指下载的屏幕,但在完成所有拇指之后才会使用完整图像进行响应.

6)询问系统你有多少RAM.

  Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo();
  Debug.getMemoryInfo(memoryInfo);
Run Code Online (Sandbox Code Playgroud)

7)" onLowMemory()"不符合你的期望.

这是因为当用户在手机上运行太多应用程序时,操作系统需要从所有正在运行的应用程序中恢复物理内存.

这与运行应用程序VM堆完全分开,就像您通过加载太多位图一样轻松完成.

据我所知,你不会收到警告,你只会崩溃(你可以用上面的电话跟踪记忆信息).

希望有助于尝试从互联网上下载和显示拇指的智能.

MIG


Ali*_*aka 3

我使用 SoftReference 来保存位图对象。该列表只需要当前可见的图像。因此,我永远不需要担心空间不足。

缺点是,当我看到图像时,向下滚动(导致一些软引用清除位图),然后再次滚动回同一位置 - 图像再次下载:(

此外,软引用的清除速度非常快。我希望他们能更长时间地保存内部位图。