【问题标题】:Android: Error loading images: OutOfMemoryError: bitmap size exceeds VM budgetAndroid:加载图像时出错:OutOfMemoryError:位图大小超出 VM 预算
【发布时间】:2012-06-02 23:01:27
【问题描述】:

我正在为平板电脑 (1024x768) 开发 Android 应用程序。我在这里搜索并找到了一些解决方案,但有人解决了我的问题。该应用程序有 5 个屏幕,每个屏幕都有一个我加载的 ImageView:

<ImageView
    android:id="@+id/imageView1"
    android:layout_width="1024dp"
    android:layout_height="768dp"
    android:layout_centerHorizontal="TRUE"
    android:src="@drawable/scene1"
    />

第一个和第二个屏幕加载良好,但是当我尝试加载第三个屏幕时,出现以下错误(我通过 startActivity 加载的每个屏幕,它的布局。这不是布局错误,因为如果我用不同的顺序,我也可以加载两个和第三个 crase):

05-28 17:03:51.774: E/AndroidRuntime(401): java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx}: android.view.InflateException: Binary XML file line #10: Error inflating class <unknown>

05-28 17:03:51.774: E/AndroidRuntime(401): Caused by: android.view.InflateException: Binary XML file line #10: Error inflating class <unknown>


05-28 17:03:51.774: E/AndroidRuntime(401): Caused by: java.lang.reflect.InvocationTargetException


05-28 17:03:51.774: E/AndroidRuntime(401): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget

我尝试了几件事:

 @Override
  public void onPause()
  {
    super.onPause();
    Log.i("URI", "Syste.gc");
    // yada yada yada...

    System.gc();
  }

@Override
protected void onDestroy()
{
    super.onDestroy();

    unbindDrawables(findViewById(R.id.RootView));
    System.gc();
}

private void unbindDrawables(View view)
{
    if (view.getBackground() != null)
    {
        view.getBackground().setCallback(null);
    }
    if (view instanceof ViewGroup)
    {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++)
        {
            unbindDrawables(((ViewGroup) view).getChildAt(i));
        }
        ((ViewGroup) view).removeAllViews();
    }
}

但我总是得到错误。

图片为PNG,重量小于50k。

有什么建议吗?

谢谢!

【问题讨论】:

  • 图像的文件大小几乎无关紧要。像素的宽度和高度是多少?
  • 1024x768 是宽度和高度,但我需要图像填满整个屏幕...

标签: java android android-layout tablet


【解决方案1】:

首先,调用 System.gc() 不会真正使垃圾收集器通过,而且它确实会影响您的性能,所以我会限制自己如此广泛地使用它。如果您希望垃圾收集器清理图像,请改用 Wea​​kReferences,并将图像存储在 HashMap 上。

其次,尝试使用较小的图像,因为虚拟机会很快崩溃。

【讨论】:

    【解决方案2】:

    1024x768 是 DP 中的尺寸,像素数可能是高分辨率设备上的两倍。

    如果您使用 bitmapfactory 解码 1024x768 图像,它将相对于密度缩放位图,因此您最终可能会得到 2048x1536 图像,这将占用大约 12MB。

    如果无论设备分辨率如何,您始终希望图像具有相同的分辨率,而不是将其放在Drawable-nodpi 文件夹中,这将导致它在解码时不会调整大小。

    【讨论】:

      【解决方案3】:

      尝试在 onCreate() 方法中加载图像,而不是从 XML 中加载。

      您是否尝试过先读取图像的尺寸和类型,然后加载该图像的缩小版本?

      正如Android developer resources 建议的那样。

      【讨论】:

      • 就是这样。我使用: public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) { // 首先使用 inJustDecodeBounds=true 解码来检查尺寸 final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resId, options); // 计算 inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // 使用 inSampleSize 设置 options.inJustDecodeBounds = false 解码位图;返回 BitmapFactory.decodeResource(res, resId, options); }
      猜你喜欢
      • 2013-01-02
      • 2010-12-07
      • 1970-01-01
      • 1970-01-01
      • 2011-02-25
      • 2011-12-21
      • 1970-01-01
      相关资源
      最近更新 更多