Mar*_*los 10 android android-image android-memory android-largeheap
在启用largeHeap选项之前,我正在处理大型位图,它几乎消耗了应用程序可用的整个内存,并且通过导航回收它并加载新的内存几乎可以在完整的堆上运行.但是,当某些操作需要更多内存时,应用程序崩溃.所以我启用largeHeap=true了更多的内存.
但这样做有一个意外的行为,它看起来像recycle()位图的方法不工作的大部分时间,并在58MB工作的内存(并超过有时抛出的应用程序OutOfMemoryException)现在消耗内存成倍而且还在不断增加(目前测试我确实来了231Mb分配的内存),预期的行为是内存管理继续工作,应用程序将不会使用超过60Mb.
我怎么能避免这种情况?还是有效地回收位图?
编辑:实际上,我OutOfMemoryError在设备上分配超过390Mb的内存时给了它一个.读取GC_*日志显示只有GC_FOR_ALLOC有时会释放3.8Mb,但几乎从未在其他GC运行中释放过某些内容.
Lal*_*ani 21
你应该看看有效地显示位图,其中包括几种有效处理大型位图的方法,
Run Code Online (Sandbox Code Playgroud)BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(getResources(), R.id.myimage, options); int imageHeight = options.outHeight; int imageWidth = options.outWidth;
这会给你的图像的尺寸在下载之前并在此基础上,你可以检查你的设备的大小,并使用它的规模calculateInSampleSize()和decodeSampledBitmapFromResource()在文档中给出的解释.
计算我们需要缩放图像的程度,
Run Code Online (Sandbox Code Playgroud)if (imageHeight > reqHeight || imageWidth > reqWidth) { if (imageWidth > imageHeight ) { inSampleSize = Math.round((float)imageHeight / (float)reqHeight); } else { inSampleSize = Math.round((float)imageWidth / (float)reqWidth); } }
Run Code Online (Sandbox Code Playgroud)int inSampleSize = Math.min(imageWidth / reqWidth,imageHeight / reqHeight);
你可以设置inSampleSize,
options.inSampleSize = inSampleSize;
Run Code Online (Sandbox Code Playgroud)
然后最后确保你打电话,
options.inJustDecodeBounds = false;
Run Code Online (Sandbox Code Playgroud)
否则它将返回Bitmap null
处理UI线程中的位图
在UI线程上处理位图永远不会安全,因此在后台线程中执行该操作总是更好,并在完成该过程后更新UI.
缓存位图
LruCache可从API 12获得,但如果您对使用以下版本感兴趣,也可以在支持库中找到它.因此,应该使用它来高效地完成图像的缓存.此外,您可以将DiskLruCache用于您希望在外部存储中保留更长时间的图像.
清除缓存
有时,当您的图像大小太大时,即使缓存图像也会导致OutOfMemoryError在这种情况下更好地清除缓存,当图像超出范围或不使用更长时间时,以便可以缓存其他图像.
我已经为此创建了一个演示示例,您可以从这里下载