I use the popular lazy download class found here: http://stackoverflow.com/questions/541966/android-how-do-i-do-a-lazy-load-of-images-in-listview/3068012 # 3068012
The problem I am facing is that I use this class in several actions, etc .... moving back and forth between actions (loading images) ultimately crashes my application, which gives me this error:
12-07 19:54:42.414: W/dalvikvm(1204): threadid=91: thread exiting with uncaught exception (group=0x4001b188) 12-07 19:54:42.424: E/AndroidRuntime(1204): Uncaught handler: thread Thread-47 exiting due to uncaught exception 12-07 19:54:42.434: E/AndroidRuntime(1204): java.lang.OutOfMemoryError: bitmap size exceeds VM budget 12-07 19:54:42.434: E/AndroidRuntime(1204): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 12-07 19:54:42.434: E/AndroidRuntime(1204): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:459) 12-07 19:54:42.434: E/AndroidRuntime(1204): at de.tablayoutexample.ImageLoader.decodeFile(ImageLoader.java:124) 12-07 19:54:42.434: E/AndroidRuntime(1204): at de.tablayoutexample.ImageLoader.getBitmap(ImageLoader.java:78) 12-07 19:54:42.434: E/AndroidRuntime(1204): at de.tablayoutexample.ImageLoader.access$0(ImageLoader.java:73) 12-07 19:54:42.434: E/AndroidRuntime(1204): at de.tablayoutexample.ImageLoader$PhotosLoader.run(ImageLoader.java:182)
The code below is part of the ImageLoader class and, I suspect, is the culprit. Initially, REQUIRED_SIZE is set to 70, which is too small. I set it to 200, which improves image quality, but the application fires faster.
Should this lazy download method clear images every time a user leaves an event? It seems to just add to the heap every time I upload more images to another action.
I am new to Android programming, so maybe someone can help me optimize this code.
//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=200; int width_tmp=o.outWidth, height_tmp=o.outHeight; int scale=1; while(true){ if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE) break; width_tmp/=2; height_tmp/=2; scale*=2; } //decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize=scale; return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); } catch (FileNotFoundException e) {} return null; }
source share