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
This commit is contained in:
John Reck
2015-07-09 17:37:34 -07:00
parent 171fe6ac0a
commit b7ba1220a3
2 changed files with 23 additions and 2 deletions

View File

@@ -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) {

View File

@@ -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();