【问题标题】:How to avoid out of memory error? [duplicate]如何避免内存不足错误? [复制]
【发布时间】:2014-07-18 17:40:04
【问题描述】:

我正在开发一个游戏,我在运行应用程序时使用BitmapFactory 加载了 52 个Bitmap files。我收到OutOfMemoryError。那是因为drawable 文件夹中的图像是.JPG 而不是.PNG?请告诉我如何解决这个问题。

【问题讨论】:

    标签: android bitmap bitmapfactory


    【解决方案1】:

    JPG vs PNG 没关系,因为当您加载位图时,您会将它们解压缩为原始数据(基本上与 bmp 相同)。未压缩,每个位图使用 4*width*height 字节。根据您的图像有多大,它可能非常大。我建议使用具有固定大小的 LRUCache 来仅在内存中保存您实际需要的图像,并剔除未使用的图像。

    【讨论】:

      【解决方案2】:

      我在我的应用程序中处理 196 张 png 图片,当我尝试加载所有图片时也遇到了内存不足的问题。我的图像是 png,这意味着将它们从 jpg 转换为 png 并没有帮助。

      我不知道这是否是最佳解决方案,但我所做的是在第一次调用时从我的主要活动的 OnCreate() 方法启动一个 IntentService。在内部,我检查是否已将较小版本的图像存储在内部存储中。如果已经创建了较小的版本,我会维护它们的列表,并在需要显示它们时在我的活动中使用它们。如果它们不存在(在用户第一次安装应用程序时发生),或者缓存从该应用程序的设置中清除,我会通过调用 decodeSampledBitmapFromResource() 以所需的宽度和高度来创建它们。所需的宽度和高度可以存储在 xml 文件中,并针对不同的屏幕。下面提供了我用于在保持图像纵横比的同时调整大小的函数。

      /**
       * Calculate in sample size.
       *
       * @param options the options
       * @param reqWidth the req width
       * @param reqHeight the req height
       * @return the int
       */
      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) {
      
              final int halfHeight = height / 2;
              final int halfWidth = width / 2;
      
              // Calculate the largest inSampleSize value that is a power of 2 and keeps both
              // height and width larger than the requested height and width.
              while ((halfHeight / inSampleSize) > reqHeight
                      && (halfWidth / inSampleSize) > reqWidth) {
                  inSampleSize *= 2;
              }
          }
      
          return inSampleSize;
      }
      
      /**
       * Decode sampled bitmap from resource.
       *
       * @param res the res
       * @param resId the res id
       * @param reqWidth the req width
       * @param reqHeight the req height
       * @return the bitmap
       */
      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);
      } 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-23
        • 2017-11-19
        • 1970-01-01
        • 1970-01-01
        • 2023-03-18
        • 2013-10-04
        相关资源
        最近更新 更多