0

In my application the user can launch a camera intent and take a picture and save it to a custom folder. They can then relaunch the camera to take a another picture etc. So in the end the user can take multiple pictures.

The problem I'm running into, is that in my gallery when I try and load all the pictures to bitmaps to place in my imageview's, I get a java.lang.OutOfMemoryError exception. I've read up somewhat about memory management but I thought I had it figured out. This is what my code looks like thus far:

File folder = new File(dir + "/");//contains anything from 1-20 pictures
File[] allPics = folder.listFiles();

private Bitmap[] thumbnails;
private String[] arrPath;

//load all the files into bitmaps to assign to my gridview adapter
for (int i = 0; i < allPics.length; i++) {
            thumbnails[i] = BitmapFactory.decodeFile(allPics[i].getAbsolutePath());//where the exception is thrown

            arrPath[i]= allPics[i].getAbsolutePath();
        }

stacktrace:

pcemobileapp E/AndroidRuntime: FATAL EXCEPTION: main
 Process: pcemobileapp, PID: 7069
 java.lang.OutOfMemoryError
     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
     at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:719)
     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:695)
     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:452)
     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:491)
     at pcemobileapp.CustomGalleryActivity.onCreate(CustomGalleryActivity.java:65)
     at android.app.Activity.performCreate(Activity.java:5459)
     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093)
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2458)
     at android.app.ActivityThread.access$900(ActivityThread.java:172)
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1305)
     at android.os.Handler.dispatchMessage(Handler.java:102)
     at android.os.Looper.loop(Looper.java:146)
     at android.app.ActivityThread.main(ActivityThread.java:5598)
     at java.lang.reflect.Method.invokeNative(Native Method)
     at java.lang.reflect.Method.invoke(Method.java:515)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
     at dalvik.system.NativeStart.main(Native Method))
4
  • 1
    Memory management in Android isn't very easy. You'll have to cache images and properly manage them with an LRUCache, even then you'll run into trouble. Use Picasso image loader, it's very easy and it'll save you a lot of headaches Commented Feb 10, 2016 at 22:03
  • thanks, I'll look into it. Commented Feb 10, 2016 at 22:03
  • 1
    It is fairly likely that the photo is much larger than the ImageView (or whatever) that you are applying it to. Use BitmapFactory.Options and inSampleSize to load something more appropriately-sized. A good library will do that for you; I think Picasso does. Commented Feb 10, 2016 at 22:06
  • I'm not going to bad mouth Picasso, but I will say this- don't jump right into using a library as a magical solution. Understand what its doing for you and why its doing that, so you can predict these types of problems in the future (and even evaluate if it would be better to do it yourself). Just blindly using a library because you're told it handles your problem is a good way to make messy broken code. Commented Feb 10, 2016 at 22:18

1 Answer 1

2

Its pretty simple here. You're decoding a bunch of photos all at once. Don't do that. You don't have enough memory on even a high end device if the number is high. Instead, save the location of the bitmap, and only inflate the bitmap in getView. If that isn't performant enough you can use an LRU cache and store the last N bitmaps in memory. But you can't just inflate a huge number of images.

Sign up to request clarification or add additional context in comments.

2 Comments

so would saving the bitmap generated by the camera in a db be better? I was thinking then about limiting the user to only 5 pictures then
Its not a matter of how the image was generated. Its a matter of the full size in memory once they're uncompressed. If an image is X wide and Y tall in pixels, the total memory uncompressed is 4*X*Y bytes. But by controlling how many of them are in memory at a time, you only need a fixed amount of memory, rather than the total amount of all images.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.