From a584c0d6fedb39b6a7c0fdedb5ff62928c9e6f90 Mon Sep 17 00:00:00 2001 From: Scott Jackson Date: Fri, 13 Mar 2015 18:17:37 -0700 Subject: Fix crash from transition drawable referencing recycled bitmap --- .../daneren2005/dsub/view/RecyclingImageView.java | 42 +++++++++++++++++++--- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/github/daneren2005/dsub/view/RecyclingImageView.java b/src/github/daneren2005/dsub/view/RecyclingImageView.java index c4fc7f0a..0c85697f 100644 --- a/src/github/daneren2005/dsub/view/RecyclingImageView.java +++ b/src/github/daneren2005/dsub/view/RecyclingImageView.java @@ -17,9 +17,11 @@ package github.daneren2005.dsub.view; import android.annotation.TargetApi; import android.content.Context; +import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.graphics.drawable.TransitionDrawable; import android.os.Build; import android.util.AttributeSet; import android.widget.ImageView; @@ -45,13 +47,45 @@ public class RecyclingImageView extends ImageView { @Override public void onDraw(Canvas canvas) { Drawable drawable = this.getDrawable(); - if(drawable != null && drawable instanceof BitmapDrawable) { - BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; - if(bitmapDrawable.getBitmap() != null && bitmapDrawable.getBitmap().isRecycled()) { - this.setImageDrawable(null); + if(drawable != null) { + if(drawable instanceof BitmapDrawable) { + if (isBitmapRecycled(drawable)) { + this.setImageDrawable(null); + } + } else if(drawable instanceof TransitionDrawable) { + TransitionDrawable transitionDrawable = (TransitionDrawable) drawable; + + // If last bitmap in chain is recycled, just blank this out since it would be invalid anyways + Drawable lastDrawable = transitionDrawable.getDrawable(transitionDrawable.getNumberOfLayers() - 1); + if(isBitmapRecycled(lastDrawable)) { + this.setImageDrawable(null); + } else { + // Go through earlier bitmaps and make sure that they are not recycled + for (int i = 0; i < transitionDrawable.getNumberOfLayers(); i++) { + Drawable layerDrawable = transitionDrawable.getDrawable(i); + if (isBitmapRecycled(layerDrawable)) { + // If anything in the chain is broken, just get rid of transition and go to last drawable + this.setImageDrawable(lastDrawable); + break; + } + } + } } } super.onDraw(canvas); } + + private boolean isBitmapRecycled(Drawable drawable) { + if(!(drawable instanceof BitmapDrawable)) { + return false; + } + + BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; + if (bitmapDrawable.getBitmap() != null && bitmapDrawable.getBitmap().isRecycled()) { + return true; + } else { + return false; + } + } } -- cgit v1.2.3