1

I'm working on implementing a cache for a lot of bitmap tiles I have. What I've done so far:

Successfully implemented a LRU Cache system, but the tiles still load slowly when they must be loaded from the app's resources. The cache currently has about an 85% hit rate.

Whenever I must load the bitmap from resources, it is still slow like I said. With this in mind, I am now loading the Bitmaps from an Async task. Before this, everything would load without error, but it was fairly slow. Now, it's faster since it's not working on the main thread, but I inevitably run into an OOM error. Here's the code for my Async task:

public class loadBitmap extends AsyncTask<Void,Void,Void>
{
    Bitmap bit;
    @Override
    protected Void doInBackground(Void... params) 
    {
        Options opts = new Options();
        bit = BitmapFactory.decodeResource(reso, drawable, opts);
        return null;
    }

    @Override
    protected void onPostExecute(Void result) 
    {
        // TODO Auto-generated method stub
        drawLoadedBit(bit);
        super.onPostExecute(result);
    }
}

Any ideas on how I can implement this so I don't get the Out of Memory error? Since this is called in the draw method, I'm thinking that the multiple calls to it are causing it. Thanks for any advice.

2
  • You may not be releasing previous bitmaps. Commented Jun 4, 2012 at 17:34
  • The thing is that I'm drawing them to a canvas. And I'm not aware of a way to recycle the bitmap only after the image is not being used on a canvas. If you do it before, you get an error. Commented Jun 4, 2012 at 17:45

2 Answers 2

1

Refer to this link

He gives a good tutorial on using regenative bitmaps. Further, to decouple the bitmap from the view [once the view is disposed], you can @Override View#onRemovedFromWindow() to recycle the bitmap. Going even further, if you still have this issue, you can create a BitmapPool in which you allocate your bitmaps. You can implement an algorithm go calculate the sizes of the bitmaps and release older bitmaps that would push you over an arbitrary memory amount (bitamp memory is about width*height*4 + object size which should be nominal)

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

Comments

0

When the Bitmap is loaded, keep it around in a class variable. Then next time a draw is requested, check to see if the class variable is non-null before loading it from resources again.

2 Comments

Unfortunately, this makes me get the OOM error even faster because then these bitmaps will always be in memory (I think). I've been using SoftReferences to do this, but from Android 2.3+ they have made collection of these much more rapid, and they aren't extremely helpful. (Less than 2.3 though, they work very well)
The bitmaps may just be too big then if you're displaying a lot of them at the same time. Android holds the bitmaps in their uncompressed form, so it's easy to hit the heap limit. You can add a sample size to that options variable that will scale the image.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.