在我的应用程序中,我将从服务器加载和显示各种图像,并且每个图像的大小没有限制。我已经与Android中的Bitmap内存使用的各种问题进行了斗争,这里有很多人抱怨,而且我已经做了很多工作,因为旧的位图正在被释放并且在我完成它们时被回收。我现在的问题是单个巨大的图像本身可能超出内存分配的可能性。我已经研究了缩小图像尺寸以节省内存的各种选项,并了解所有工作原理 - 我的问题是我希望尽可能保持图像质量,所以我希望Bitmap使用尽可能多的内存它可以不杀死一切。
所以,我的问题是,鉴于存在各种具有不同内存容量的设备,有没有办法在运行时确定合适的最大大小,以便平衡内存分配和图像质量?
答案 0 :(得分:4)
我发现自己有类似的问题。经过一些研究和测试后,我提出了许多方法来帮助我完成这个主题。这些是使用C#使用Mono for Android实现的,但我猜它们应该与Java几乎相同:
/// <summary>
///Calculates the memory bytes used by the given Bitmap.
/// </summary>
public static long GetBitmapSize(Android.Graphics.Bitmap bmp)
{
return GetBitmapSize(bmp.Width, bmp.Height, bmp.GetConfig());
}
/// <summary>
///Calculates the memory bytes used by a Bitmap with the given specification.
/// </summary>
public static long GetBitmapSize(long bmpwidth, long bmpheight, Android.Graphics.Bitmap.Config config)
{
int BytesxPixel = (config == Android.Graphics.Bitmap.Config.Rgb565) ? 2 : 4;
return bmpwidth * bmpheight * BytesxPixel;
}
/// <summary>
///Calculates the memory available in Android's VM.
/// </summary>
public static long FreeMemory()
{
return Java.Lang.Runtime.GetRuntime().MaxMemory() - Android.OS.Debug.NativeHeapAllocatedSize;
}
/// <summary>
///Checks if Android's VM has enough memory for a Bitmap with the given specification.
/// </summary>
public static bool CheckBitmapFitsInMemory(long bmpwidth, long bmpheight, Android.Graphics.Bitmap.Config config)
{
return (GetBitmapSize(bmpwidth, bmpheight, config) < FreeMemory());
}
该代码证明非常可靠,可防止内存不足异常。在名为 Utils 的命名空间中使用这些方法的示例是下面的代码片段。此代码计算3个位图所需的内存,其中两个是第一个位图的3倍。
/// <summary>
/// Checks if there's enough memory in the VM for managing required bitmaps.
/// </summary>
private bool NotEnoughMemory()
{
long bytes1 = Utils.GetBitmapSize(this.Width, this.Height, BitmapConfig);
long bytes2 = Utils.GetBitmapSize(this.Width * 3, this.Height * 3, BitmapConfig);
return ((bytes1 + bytes2 + bytes2) >= Utils.FreeMemory());
}