Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7ba1220 authored by John Reck's avatar John Reck
Browse files

Teach ImageView to recycle internal drawables

Bug: 22289362

It's pretty common for ImageView#setBitmap to be called
repeatedly. Avoid re-creating the BitmapDrawable in this scenario
as that has high object churn of semi-expensive objects like
Paint.

Change-Id: Ib77719cd0366d02c1a42f774850bf3b9caa9c288
parent 171fe6ac
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -570,6 +570,17 @@ public class ImageView extends View {
        }
    }

    private static class ImageViewBitmapDrawable extends BitmapDrawable {
        public ImageViewBitmapDrawable(Resources res, Bitmap bitmap) {
            super(res, bitmap);
        }

        @Override
        public void setBitmap(Bitmap bitmap) {
            super.setBitmap(bitmap);
        }
    };

    /**
     * Sets a Bitmap as the content of this ImageView.
     * 
@@ -579,7 +590,16 @@ public class ImageView extends View {
    public void setImageBitmap(Bitmap bm) {
        // if this is used frequently, may handle bitmaps explicitly
        // to reduce the intermediate drawable object
        setImageDrawable(new BitmapDrawable(mContext.getResources(), bm));
        if (mDrawable instanceof ImageViewBitmapDrawable) {
            ImageViewBitmapDrawable recycledDrawable = (ImageViewBitmapDrawable) mDrawable;
            // Hacky fix to force setImageDrawable to do a full setImageDrawable
            // instead of doing an object reference comparison
            mDrawable = null;
            recycledDrawable.setBitmap(bm);
            setImageDrawable(recycledDrawable);
        } else {
            setImageDrawable(new ImageViewBitmapDrawable(mContext.getResources(), bm));
        }
    }

    public void setImageState(int[] state, boolean merge) {
+2 −1
Original line number Diff line number Diff line
@@ -219,7 +219,8 @@ public class BitmapDrawable extends Drawable {
        }
    }

    private void setBitmap(Bitmap bitmap) {
    /** @hide */
    protected void setBitmap(Bitmap bitmap) {
        if (mBitmapState.mBitmap != bitmap) {
            mBitmapState.mBitmap = bitmap;
            computeBitmapSize();