Bitmap memory management is buggy and completely unintuitive. It does
not show in MAT as it is allocated in another place and not counted in
the heap. Well it is counted but not easily released or something.

My app is all about images(a world of faces), and here is how I get it
to work most of the time :

    //decodes image and scales it to reduce memory consumption
    private Bitmap decodeFile(File f){
        try {

            //decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f),null,o);

            //Find the correct scale value. It should be the power of
2.
            final int REQUIRED_SIZE=480;
            int width_tmp=o.outWidth, height_tmp=o.outHeight;
            int sampleSize=1;
            while(true){
                if(width_tmp/2<REQUIRED_SIZE || height_tmp/
2<REQUIRED_SIZE)
                    break;
                width_tmp/=2;
                height_tmp/=2;
                sampleSize*=2;
            }


                //decode with inSampleSize
            Bitmap bitmap = null;
            boolean cacheHasBeenCleared = false;

            BitmapFactory.Options options = new
BitmapFactory.Options();
            options.inSampleSize=sampleSize;
            byte[] tempBuffer=new byte[8000];
                options.inTempStorage = tempBuffer;

                while ( (bitmap == null) && (sampleSize < 64) ) {
                        try {
                                bitmap = BitmapFactory.decodeStream(new 
FileInputStream(f),
null, options);
                        } catch (OutOfMemoryError e) {

                                if (!cacheHasBeenCleared) {
                                        this.clearMemoryCache();

                                        //Try to free up some memory
                                        System.gc();
                                        System.runFinalization();
                                        System.gc();

                                        cacheHasBeenCleared = true;
                                }

                                sampleSize *=2;
                        }
                }

            return bitmap;

        } catch (FileNotFoundException e) {}
        return null;
    }

The idea is to try to decode the file at top quality. If that throws
out of memory error, it tries to free memory and reopen the file but
with a smaller scale. Rinse and repeat.

Oh and don't think the second system.gc() can be removed that would be
so naïve of you :D That's Android framework we're talking about :D

Good luck with your app.

Yahel

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to