androidopengl-es-2.0bitmapfactorybitmapdrawable

Issue when recycling bitmap obtained from 'BitmapDrawable'


I'm loading a bitmap to use as a texture in my OpenGLES 2.0 app

If I load and use the bitmap via Bitmapfactory then all is OK. Like so:

Load

 public void loadBitmaps{

    backgrounds= BitmapFactory.decodeResource(view.getResources(), R.drawable.backgrounds, BMFOptions);
    ...

Use

//Apply as texture to OpenGL Quad

Recycle

backgrounds.recycle();

.

Now, the problem...........

.

When I load the bitmap as a bitmapDrawable, I get problems (explained below code). Like so:

.

Declare BitmapDrawable at class level

public class Res{

    BitmapDrawable bd;
    ...

Load

public void loadBitmaps(){

    bd = (BitmapDrawable) view.getResources().getDrawable(R.drawable.backgrounds);
    backgrounds = bd.getBitmap();
    ...

Use

//Apply as texture to OpenGL Quad

Recycle

backgrounds.recycle();

When doing this, it works the first time, but if I then press back to exit, and relaunch the app, the textures don't show and all I get are black quads.

If I do any of the following it solves the problem and I would like to know why......

BitmapDrawable bd = (BitmapDrawable) view.getResources().getDrawable(R.drawable.backgrounds);

bd = null;

Note I need to access the bitmap in this way rather than using BitmapFactory as I'm accessing it via an XML Alias.


Solution

  • Drawable instances are cached and shared, so when you do a call to getDrawable() it will load the one it currently has cached rather than creating a new bitmap. If you recycle the underlying bitmap, that's going to cause problems with future uses. What you likely want to do is make a copy of the drawable before modifying it:

    BitmapDrawable bmpDrawable = (BitmapDrawable) view.getResources()
            .getDrawable(R.drawable.backgrounds);
    Bitmap original = bmpDrawable.getBitmap();
    Bitmap copy = original.copy(original.getConfig(), true);
    

    See this blog post for more info on drawable mutations.