Save bitmap from custom view that has animation going through onDraw method

So, I have an animation created with a bunch of bitmaps drawn in the onDraw () method of a custom view. There is a stream of updates that calls a method on the custom view that changes the positions of the bitmaps to be drawn with the onDraw () method. I would like to do this in order to keep the bitmap generated every time the update stream is finished so that I can create a gif from the bitmaps that I save.

I found the below code to save a png from a bitmap stored in memory on an SD card and that works with the saved bitmap, but I am having problems with getDrawingCache ():

public void saveView(){
    if(counter < 200){
        try {
            System.out.println("Counter : " + counter);
            File file = new File(path, "star"+counter+".png");
            OutputStream fOut = new FileOutputStream(file);
            getDrawingCache().compress(Bitmap.CompressFormat.PNG, 100, fOut);
        } catch (Exception e) {


Doing this essentially does two things right now:

1) It takes about 50 images and saves them on the SD card. @ about 50, this forces the heap to get to the big one (I think destroyDrawingCache () can't actually finish because of this in a separate thread)

2) In the pictures taken, you can see the scan lines from the buffer update, because I am taking from the buffer that is being updated.

It would seem that getDrawingCache is calling onDraw (), so I cannot have this on the UI thread in onDraw itself.

If possible, please help.


source to share

1 answer

You shouldn't call getDrawingCache()

from outside the UI. This is why the bitmaps you received have partially updated the scan lines. Call saveView()

directly from onDraw()

. Only file operations can be performed on separate threads after a clone of the cached bitmap is created.

Note. Can you call setDrawingCacheEnabled(true)

? so you don't need to call buildDrawingCache()

and destroyDrawingCache()

. Also, if your device is hardware accelerated, you need to make a call setLayerType(LAYER_TYPE_SOFTWARE, null)


Another solution is to get a bitmap by calling View.draw(

on a new canvas containing an empty bitmap.



All Articles