我正在使用显示文本和图像的列表视图。我试图使用Task对象异步下载图像并在视图中加载它们以使列表视图有效滚动。但是我经常得到OutOfMemoryExceptions,因为内存中有太多的位图,即使我将它们保存到光盘并访问它。我看到的一个原因是创建了许多任务(对于20个图像,创建了20个任务),它也可能占用内存。有没有一种有效的方法呢?
以下是code
答案 0 :(得分:1)
您必须缩放位图,以便它们不会以完全分辨率加载到内存中。内存中100kb的位图是400kb,因为您需要为每个像素分配4bytes来保存Alpha,Red,Green和Blue的所有颜色值。如果您使用相机拍摄图像,它们很容易变成10倍大小,并且很快会占用大量内存。
我看到你在DecodeSampledBitmap
缩放图像,但是当你不再需要它时你也需要处理它。
在SetBitmap
中,您忘了处理您的位图,您可以简单地在其周围添加using
语句:
using(var bitmap = ImageDownloader.DownloadImage( url, width, height ))
{
if( !token.IsCancellationRequested )
(this.m_context as Activity).RunOnUiThread(
() => imageView.SetImageBitmap( bitmap )
);
}
请同时查看Xamarin文档中的Load Large Bitmaps Efficiently article。
答案 1 :(得分:0)
除了有效加载位图之外,我最近发现确保Android知道它可以在以后发布图像也很重要。
其中一个可用的解码选项是InPurgeable
,如果您希望Android从内存中清除任何已加载的位图,则将其设置为true
非常重要。
如果将其设置为true,则生成的位图将分配其像素,以便在系统需要回收内存时可以清除它们。在这种情况下,当需要再次访问像素时(例如,绘制位图,调用getPixels()),它们将被自动重新解码
请参阅: