3

I am using ViewFlipper in my android app. After calling startflipping() if I let app to run for some minutes I get soon the error :

11-22 15:36:34.354: ERROR/dalvikvm-heap(428): 307200-byte external allocation too large for this process.
11-22 15:36:34.372: ERROR/(428): VM won't let us allocate 307200 bytes
11-22 15:36:34.375: ERROR/AndroidRuntime(428): Uncaught handler: thread main exiting due to uncaught exception
11-22 15:36:34.384: ERROR/AndroidRuntime(428): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
11-22 15:36:34.384: ERROR/AndroidRuntime(428):     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
11-22 15:36:34.384: ERROR/AndroidRuntime(428):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:459)
11-22 15:36:34.384: ERROR/AndroidRuntime(428):     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:271)
11-22 15:36:34.384: ERROR/AndroidRuntime(428):     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:296)
11-22 15:36:34.384: ERROR/AndroidRuntime(428):     at com.PlayerOrange.ViewPlaylist.populate(ViewPlaylist.java:115)
11-22 15:36:34.384: ERROR/AndroidRuntime(428):     at com.PlayerOrange.ViewPlaylist.access$0(ViewPlaylist.java:100)
11-22 15:36:34.384: ERROR/AndroidRuntime(428):     at com.PlayerOrange.ViewPlaylist$ProgressTask$1$1.run(ViewPlaylist.java:383)

Every 30 seconds I get some info about memory like this :

ActivityManager activityManager = (ActivityManager) getBaseContext().getSystemService(ACTIVITY_SERVICE);
                android.app.ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
                activityManager.getMemoryInfo(memoryInfo);

                Log.i(TAG, " memoryInfo.availMem " + memoryInfo.availMem + "\n" );
                Log.i(TAG, " memoryInfo.lowMemory " + memoryInfo.lowMemory + "\n" );
                Log.i(TAG, " memoryInfo.threshold " + memoryInfo.threshold + "\n" );

What's strange is that before I get Force Close (for outofmemoryError) I have in DDMS this :

11-22 15:36:10.255: INFO/(428):  memoryInfo.availMem 50470912
11-22 15:36:10.255: INFO/(428):  memoryInfo.lowMemory false
11-22 15:36:10.264: INFO/(428):  memoryInfo.threshold 16777216

I have no idea how to solve this error.

Here is my code for populating ViewFlipper:

private void populate() {
        for (int i = 0; i < jArray.length(); i++) {
            System.out.println("lungime" + jArray.length());
            LinearLayout l = new LinearLayout(this);
            l.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
                    LayoutParams.FILL_PARENT));
            l.setBackgroundColor(0x000000);
            l.setOrientation(LinearLayout.VERTICAL);
            vf.addView(l);

            File f = new File(Environment.getExternalStorageDirectory()
                    + "/Downloads/");

            File[] files = f.listFiles();

            Bitmap bitmap = BitmapFactory.decodeFile(files[i].getPath());
            img = new ImageView(this);
            img.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
                    LayoutParams.FILL_PARENT));

            img.setImageBitmap(bitmap);

            System.out.println("target " + target[i]);
            img.setOnTouchListener(this);
            img.setId(i);

            l.addView(img);
            img = null;

        }

vf = (ViewFlipper) findViewById(R.id.details);
            vf.setFlipInterval(Integer.valueOf(timer) * 1000);
            vf.startFlipping();
            populate();

I get the images from web and save to Sdcard. After that I get them from folder of SDcard and add them to viewFlipper.

Any idea is welcome. Thanks in advance.

Gabrielle
  • 4,933
  • 13
  • 62
  • 122

3 Answers3

1
  1. Use some caching mechanism to reduce the memory usage.
  2. Scale the images down using BitmapFactory.Options http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html

Caching here means to use some sort of data structure that can keep efficient references to your images. This just means that you can access the images as needed, through your cache, and the cache will try to only keep references to the images that are needed, as demanded. This is typically done by using SoftReference: http://download.oracle.com/javase/6/docs/api/java/lang/ref/SoftReference.html or even WeakReference: http://download.oracle.com/javase/6/docs/api/java/lang/ref/WeakReference.html

Here's an example: https://github.com/thest1/LazyList

LuxuryMode
  • 33,401
  • 34
  • 117
  • 188
1

You're simply using too many & too large Bitmap images.

If you have too many images in memory at once it will cause an OutOfMemoryException because Bitmaps are really just huge 2 dimensional arrays.

As said in other answer you can do two different things: reducing the size of the images or reducing the amount of images in memory at once.

You could use caching or weak references, you could scale down the bitmaps on the fly. These are comparatively advanced techniques. You're best bet, if possible is to simply use much smaller bitmaps as your source.

If you can't, here's a simple solution:

        img.setImageBitmap(bitmap);
        bitmap.recycle();
        System.out.println("target " + target[i]);

This should more promptly clear up the Bitmap object. See the following for more info: recycle.

Graeme
  • 25,714
  • 24
  • 124
  • 186
  • Hi Graeme, when i try as said by you here, than i got this error : Canvas: trying to use a recycled bitmap android.graphics.Bitmap Can you give any suggestion .....? – Kalpesh Dec 22 '11 at 11:31
  • Once you have recycled a bitmap it is destroyed and cleaned by the Garbage Collected and it's memory is release for reuse. It is no longer available to use once recycled. – Graeme Dec 22 '11 at 11:33
  • you right but....my code is like...: File folder=new File(GlobalPhotoPrivacy.savedImagesFolderPath+"/"+rowId); File[] files=folder.listFiles(); for(int i=0;i – Kalpesh Dec 22 '11 at 11:39
  • You should recycle the bitmap after it's loaded to the page. – Graeme Dec 22 '11 at 11:57
  • I am first loaded all ImageView into pager and than in background thread by use of for loop I am set bitmap to it and after set I going to recycle it....Where are going to mistake ? – Kalpesh Dec 23 '11 at 04:26
  • You are only setting a reference to the bitmap. There is no memory copying going on. If you say "The bitmap is at position 4" and then delete the bitmap later in the lifecycle when they check position 4 it won't find the bitmap. – Graeme Dec 23 '11 at 09:05
0

Related to below its already questioned and answered by experts.

OutOfMemoryError: bitmap size exceeds VM budget

check out below link:

Strange out of memory issue while loading an image to a Bitmap object

Community
  • 1
  • 1
RobinHood
  • 10,897
  • 4
  • 48
  • 97