4

私のアプリケーションでは、サーバーからさまざまな画像を読み込んで表示します。各画像のサイズに制限はありません。私はすでにAndroidでのビットマップのメモリ使用量のさまざまな問題と戦い、多くの人がここで不満を言っています。古いビットマップがリリースされ、使い終わったらリサイクルされるという点で、多くの作業を行っています。 。私の今の問題は、単一の巨大な画像がそれ自体でメモリ割り当てを超える可能性があることです。私はすでにメモリを節約するために画像をダウンサイジングするためのさまざまなオプションを調べて、すべてがどのように機能するかを調べました-私の問題は、可能な限り画質を維持したいので、ビットマップができるだけ多くのメモリを使用することを望んでいますそれはすべてを殺すことなくできます。

それで、私の質問は、メモリ容量が異なる非常に多種多様なデバイスがあることを考えると、メモリ割り当てと画質のバランスをとるために、実行時に適切な最大サイズを決定する方法はありますか?

4

1 に答える 1

4

私は同様の問題を抱えていることに気づきました。いくつかの調査とテストの後、私はその主題に役立つ多くの方法を思いつきました. これらは Mono for Android を使用して C# で実装されていますが、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 つのビットマップに必要なメモリを計算します。そのうちの 2 つは最初のビットマップの 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 に答える