Android:加载图片时出错:OutOfMemoryError:位图大小超过VM预算

时间:2012-05-28 15:24:18

标签: java android android-layout tablet

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

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

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

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。

有什么建议吗?

谢谢!

3 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:1)

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

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

正如Android developer resources建议的那样。

答案 2 :(得分:0)

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

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