4

在我的应用程序中,我将加载和显示来自服务器的各种图像,并且每个图像的大小没有限制。我已经与许多人在这里抱怨的 Android 中位图内存使用的各种问题进行了斗争,而且我已经做了很多工作,当我完成旧位图时,它们会被释放和回收. 我现在的问题是单个巨大图像本身超出内存分配的可能性。我已经研究了缩小图像大小以节省内存并了解所有工作原理的各种选项 - 我的问题是我想尽可能地保持图像质量,所以我希望位图使用尽可能多的内存它可以不杀死一切。

所以,我的问题是,鉴于内存容量不同的设备种类繁多,有没有办法在运行时确定合适的最大大小,以平衡内存分配和图像质量?

4

1 回答 1

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());
}
于 2012-10-16T11:53:45.737 回答