我正在开发一个Android应用程序,它在几个活动中使用多个大图像。每个图像大约是1280x800,我为每个活动加载了大约2-4个这样的图像。我意识到这些图像在分配给设备上每个应用程序的内存方面非常大,但我如何才能在不遇到java.lang.OutOfMemory错误的情况下以原始分辨率显示它们?我需要这些图像以它们的完整尺寸显示在屏幕上(当屏幕比图像小时,缩放由xml自动完成)。我看到了几种解决方案,包括将图像缩小为缩略图并将其存储到内存中,但这不会导致图像失去其原始大小/分辨率吗?谢谢你的帮忙!
发布于 2013-01-10 01:16:14
This article很好地描述了如何创建堆转储并使用Eclipse MAT对其进行分析。这将帮助您快速找到内存泄漏的最有可能的嫌犯。
我再一次向你指出this great link,我从另一个问题中找到了如何正确解决这个问题的教程。
发布于 2013-01-10 01:04:52
对此您可以做几件事。
首先想到的是1280x800 (可能)是您的整个屏幕,所以您应该一次只显示一个屏幕。当你这样做的时候,不要把其他的东西留在内存中。
每像素4字节的1280x800图像仍然只有4MB,而且现在平板电脑似乎都提供了48MB的堆。如果需要,您应该能够在内存中保留一些。如果内存不足,则可能是内存泄漏。如果您在DDMS中观察,您的内存使用量是否会随着您更改活动而继续增长?
泄漏的一个常见来源是位图本身。当你用完它们时,一定要调用Bitmap#recycle。
如果确实如此,并且您无法适应所提供的堆空间,那么您还可以尝试将android:largeHeap="true"添加到清单中的应用程序标记中。这将要求系统为您提供更多的堆空间-在某些设备上高达256MB。不过,这应该是最后的手段,因为它会因设备而异,在一些设备上完全被忽略(脑海中浮现出最初的Kindle Fire )。
您可以使用Runtime.getRuntime().maxMemory();查看您拥有的总堆空间大小。有关详细说明,请参阅this answer。要知道你到底使用了多少比较棘手,但如果你想解决这个问题,有一个here描述。
最后,可能有一种比在xml中指定图像更好的加载图像的方法。请务必阅读此developer guide page。即使您必须将它们保留在xml中,但通过将图像资产拆分到drawable-hdpi、drawable-mdpi等目录中,而不只是将它们转储到drawable中,我已经看到了内存使用的显著改进。
发布于 2013-01-10 04:21:34
在使用BitmapFactory或相关方法加载图像之前,需要对图像进行缩放。
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float)height / (float)reqHeight);
} else {
inSampleSize = Math.round((float)width / (float)reqWidth);
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}整个事情都在Android开发者网站Loading Large Bitmaps Efficiently中进行了解释。
https://stackoverflow.com/questions/14242318
复制相似问题