0

I'm developing an Android Application for a tablet (1024x768). I searched and find some solutions here, but anyone solved me the problem. The application has 5 screens and each screen has an ImageView that I load:

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

The first and the second screen loads good, but when I try to load the third one, I get the following errors (Every screen I load by startActivity which its layout. It's not a layout error, because if I load them with a different order, I can load two and the third one crases too):

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

I tried several things:

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

    System.gc();
  }

and

@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();
    }
}

but I always get the error.

The images are PNG and its weight is lower than 50k.

Any suggestions?

Thanks!

oriolpons
  • 1,883
  • 12
  • 20

3 Answers3

1

1024x768 is the dimensions in DP, the number of pixels could be up to twice that on a high resolution device.

If you decode a 1024x768 image with a bitmapfactory it will scale the bitmap relative to density, so you could end up with a 2048x1536 image, which would take up something like 12MB.

If you always want the image to be the same resolution regardless of device resolution, than put it in the Drawable-nodpi folder, that will cause it not to be resized on decode.

Tim
  • 35,413
  • 11
  • 95
  • 121
1

Try to load the image in the onCreate() method instead of loading it from the XML.

Have you tried to first read the dimensions and type of the image, and then load a scaled down version of that image?

As the Android developer resources suggest.

Javier Gonzalez
  • 915
  • 6
  • 14
  • That's it. I used: 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); } – oriolpons May 28 '12 at 21:27
0

first of all, calling System.gc() won't really make the Garbage Collector pass, and it can really hinder your performance so I'd restrain myself from using it so widely. If you want the garbage collector to clean the images, use WeakReferences instead, and store the images on a HashMap.

Second of all, try to use smaller images, as the VM will quickly collapse instead.

Charlie-Blake
  • 10,832
  • 13
  • 55
  • 90