Xavi
Xavi

Reputation: 162

Working with bitmaps in separate threads

I'm working in a project that opens an image, plays with it, and saves. The image can be a very huge image, like a camera pic, so I'm doing several things to ensure not getting OutOfMemory exceptions (basically what appears here http://developer.android.com/training/displaying-bitmaps/load-bitmap.html):

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(image_path, options);

But, in some cases, when it's impossible to have only one bitmap loaded at a time to do a certain work (rotating the image, fine tune resizing, apply masks, ...), and mostly in medium range or old devices, I get an OutOfMemory Exception.

I've started to add all the Image working in Background Jobs with something like the following (ok, I'm a newbie):

ProgressDialog dialog = ProgressDialog.show(this, null, "Please wait", true, false);
new Thread(new BackgroundJob(this, new Runnable() {
    public void run() {
        ImageHelper.ImageManipulation(image_path); 
    }
}, dialog, new Handler())).start();

I was hoping to get a completely memory free space with this new thread to perform there the Image manipulation tasks, but what I find is that the app crashes at same points for same reasons. Threads are created as a child process (ok) but sharing the max heap and the current used mem ...

Is there a way to open a thread to perform image manipulation having more memory to work (freeing the memory used by the activity itself as it is another thread, for example)?

Thank you very much.

Upvotes: 1

Views: 2549

Answers (2)

nikib3ro
nikib3ro

Reputation: 20596

There is lots of gotcha's when it comes to memory management on Android devices - especially when you throw in different devices into the mix. I've wasted last year playing with memory management in different Android apps I've made and it was not until I found Android-BitmapCache project that I made some significant progress.

I advise everyone who are interested in Android Memory management to download and inspect Android-BitmapCache project, because it contains some great code - so do that as a first step.

I would advise that your second step would be watching Google I/O: Memory Management for Android Apps mostly so you can start testing exactly how much your application is using memory, and tracking where EXACTLY memory usage starts increasing. Speaking of that - I don't understand why you think that you'll get "completely memory free space with new thread" - all threads that you spawn from your Android app will be under same process, so it doesn't matter which exact thread is running some task when it comes to memory usage.

And finally, you can fix problem temporary by using android:largeHeap="true", but I think you should definitely aim toward more robust solution. Keep in mind that it's possible that on some devices you app will simply not work (24MB heap and you want to load image that's 3000x3000), but with applying all best practices you can find in project I've linked I'm sure you'll be much better off.

Upvotes: 3

Rodion Altshuler
Rodion Altshuler

Reputation: 1783

You could use pool thread to execute multiple threads, it's less "expensive" way comparing to create new Thread object for every thread.

This guide might help: http://developer.android.com/training/multiple-threads/create-threadpool.html

Or this http://android-developers.blogspot.com/2009/05/painless-threading.html

Upvotes: 1

Related Questions