Skip to content
Browse files

[library] Improve code around drawing recycled Bitmaps:

- We now disable recycling IF the Drawable isn't being displayed in a CacheableImageView
- We now record the method stack which caused the recycle call. This will help debugging problems later.
  • Loading branch information...
1 parent ffef321 commit 4672768e983c1847a76e06e4cde0806c29086e99 @chrisbanes committed Mar 11, 2013
Showing with 34 additions and 1 deletion.
  1. +34 −1 library/src/uk/co/senab/bitmapcache/CacheableBitmapDrawable.java
View
35 library/src/uk/co/senab/bitmapcache/CacheableBitmapDrawable.java
@@ -18,6 +18,7 @@
import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.os.Handler;
import android.os.Looper;
@@ -30,7 +31,7 @@
// URL Associated with this Bitmap
private final String mUrl;
- private final BitmapLruCache.RecyclePolicy mRecyclePolicy;
+ private BitmapLruCache.RecyclePolicy mRecyclePolicy;
// Number of Views currently displaying bitmap
private int mDisplayingCount;
@@ -44,6 +45,9 @@
// The CheckStateRunnable currently being delayed
private Runnable mCheckStateRunnable;
+ // Throwable which records the stack trace when we recycle
+ private Throwable mStackTraceWhenRecycled;
+
// Handler which may be used later
private static final Handler sHandler = new Handler(Looper.getMainLooper());
@@ -57,6 +61,24 @@
mCacheCount = 0;
}
+ @Override
+ public void draw(Canvas canvas) {
+ checkCallback();
+
+ try {
+ super.draw(canvas);
+ } catch (RuntimeException re) {
+ // A RuntimeException has been thrown, probably due to a recycled Bitmap. If we have
+ // one, print the method stack when the recycle() call happened
+ if (null != mStackTraceWhenRecycled) {
+ mStackTraceWhenRecycled.printStackTrace();
+ }
+
+ // Finally throw the original exception
+ throw re;
+ }
+ }
+
/**
* @return Amount of heap size currently being used by {@code Bitmap}
*/
@@ -141,6 +163,14 @@ private void cancelCheckStateCallback() {
}
}
+ private void checkCallback() {
+ if (!(getCallback() instanceof CacheableImageView)) {
+ mRecyclePolicy = BitmapLruCache.RecyclePolicy.DISABLED;
+ Log.w(LOG_TAG,
+ "CacheableBitmapDrawable should only be used with CacheableImageView. Turning off all recycling functionality");
+ }
+ }
+
/**
* Calls {@link #checkState(boolean)} with default parameter of <code>false</code>.
*/
@@ -188,6 +218,9 @@ private synchronized void checkState(final boolean ignoreBeenDisplayed) {
if (Constants.DEBUG) {
Log.d(LOG_TAG, "Recycling bitmap with url: " + mUrl);
}
+ // Record the current method stack just in case
+ mStackTraceWhenRecycled = new Throwable("Recycled Bitmap Method Stack");
+
getBitmap().recycle();
} else {
if (Constants.DEBUG) {

0 comments on commit 4672768

Please sign in to comment.
Something went wrong with that request. Please try again.