【问题标题】:Choosing a max bitmap size for memory concerns为内存问题选择最大位图大小
【发布时间】:2012-10-06 10:31:24
【问题描述】:

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

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

【问题讨论】:

    标签: android memory bitmap heap-memory


    【解决方案1】:

    我发现自己也有类似的问题。经过一些研究和测试,我想出了一些方法来帮助我解决这个问题。这些是用 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 的命名空间中使用这些方法的示例是下面的代码 sn-p。此代码计算 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());
    }
    

    【讨论】:

    • 经过一些语法更改后在 Java 中可以正常工作。
    猜你喜欢
    • 2013-08-20
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 1970-01-01
    • 2011-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多