A software engineer focused on all things UI
chrisbanes / android-bitmapcache Goto Github PK
View Code? Open in Web Editor NEWAndroid-BitmapCache is a specialised cache, for use with Android Bitmap objects.
Android-BitmapCache is a specialised cache, for use with Android Bitmap objects.
I'm having issues with the implementation of the BitmapLruCache$RecyclePolicy.canInBitmap method. Here is how it stands:
boolean canInBitmap() {
switch (this) {
case PRE_HONEYCOMB_ONLY:
case DISABLED:
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
}
return false;
}
This implies that it will return true (e.g. bitmaps can be re-used) when the policy is set to DISABLED (and you are running on a post-honeycomb device), which i believe is incorrect. May i suggest the following:
boolean canInBitmap() {
switch (this) {
case PRE_HONEYCOMB_ONLY:
return Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB;
case DISABLED:
return false;
}
return true;
}
Is there a specific reason that BitmapLruCache
caches the BitmapDrawable
s as opposed to the Bitmap
objects themselves?
I want to use this library for caching decoded resources that will eventually be drawn on canvas (canvas.drawBitmap()
). My custom View
does not have a drawable to speak of. I could still use the CacheableBitmapDrawable
just for the cache (and then extract out the Bitmap
from the drawable that I get from the cache), but this does not seem clean.
Hello,
I am frequently getting the OOME exception when using this lib to view pictures from server. Here is the exception callback:
07-17 23:00:01.230: E/AndroidRuntime(10272): Caused by: java.lang.OutOfMemoryError
07-17 23:00:01.230: E/AndroidRuntime(10272): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
07-17 23:00:01.230: E/AndroidRuntime(10272): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:493)
07-17 23:00:01.230: E/AndroidRuntime(10272): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:299)
07-17 23:00:01.230: E/AndroidRuntime(10272): at uk.co.senab.bitmapcache.BitmapLruCache.put(BitmapLruCache.java:425)
Note that the "mDecodeOpts" is setting as below:
if (!fullSize) {
decodeOpts = new BitmapFactory.Options();
decodeOpts.inDensity = DisplayMetrics.DENSITY_XHIGH;
decodeOpts.inPurgeable = true;
decodeOpts.inInputShareable = true;
decodeOpts.inScaled = true;
}
Thanks in advance for any comment or suggestion!
This line fails with:
E/AndroidRuntime( 2918): java.lang.NoSuchMethodError: uk.co.senab.bitmapcache.CacheableBitmapDrawable.getCallback
E/AndroidRuntime( 2918): at uk.co.senab.bitmapcache.CacheableBitmapDrawable.checkCallback(CacheableBitmapDrawable.java:167)
E/AndroidRuntime( 2918): at uk.co.senab.bitmapcache.CacheableBitmapDrawable.draw(CacheableBitmapDrawable.java:66)
E/AndroidRuntime( 2918): at android.widget.ImageView.onDraw(ImageView.java:872)
E/AndroidRuntime( 2918): at android.view.View.draw(View.java:6902)
I guess you will have to intercept the setCallback method and store the callback yourself. Too bad setCallback is API 1 and getCallback is API 11. Confusing mistake by google.
Btw. You do not run lint to check against such errors?
Hi.
Getting NullpointerException if MemoryCache is disabled.
BitmapLruCache.java:560
...
BitmapLruCache.Builder builder = new BitmapLruCache.Builder(App.getContext());
builder.setMemoryCacheEnabled(false);
builder.setDiskCacheEnabled(true).setDiskCacheLocation(cacheLocation);
...
Feature?
Dear Chrisbanes,
Thank you for your support.
I just want to know that this library using any Encoding/encryption processing, if yes could you please give some information about it, if possible.
Thanks in advance.
Would you consider adding a method along the lines of isDiskCacheEnabled()
to the API? It is useful to know this because if disk cache is not enabled, I can perform operations synchronously instead of having to do them off the main thread.
If I add the line below to my gradle config on a library project then the app using that library crashes as soon as I touch the screen. I am not even using the library yet.
compile 'com.github.chrisbanes.bitmapcache:library:2.3+'
This is the crash
Process: mypacakge, PID: 8762
java.lang.NoSuchMethodError: No static method getPointerCount(Landroid/view/MotionEvent;)I in class Landroid/support/v4/view/MotionEventCompatEclair; or its super classes (declaration of 'android.support.v4.view.MotionEventCompatEclair' appears in /data/app/mypackage-2/base.apk:classes39.dex)
at android.support.v4.view.MotionEventCompat$EclairMotionEventVersionImpl.getPointerCount(MotionEventCompat.java:99)
at android.support.v4.view.MotionEventCompat.getPointerCount(MotionEventCompat.java:236)
at android.support.v4.widget.ViewDragHelper.shouldInterceptTouchEvent(ViewDragHelper.java:1007)
at android.support.v4.widget.DrawerLayout.onInterceptTouchEvent(DrawerLayout.java:1137)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1960)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2369)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1719)
at android.app.Activity.dispatchTouchEvent(Activity.java:2742)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2330)
at android.view.View.dispatchPointerEvent(View.java:8666)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4123)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3989)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3680)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3737)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5807)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5781)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5752)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5897)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:176)
at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:5868)
at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:5920)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:548)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Hand
Happens on Android 5.1 on a Nexus 6 and 7 running without proguard. When I try to run proguard I get the following:
Error:Execution failed for task ':app:proguardProdRelease'.
> java.io.IOException: Can't write [/workspace/android/app/build/intermediates/classes-proguard/prod/release/classes.jar] (Can't read [/homedir/.gradle/caches/modules-2/files-2.1/com.google.android/support-v4/r7/24d0f6da34c3a2bfcf736ab42d51c91ac821ee22/support-v4-r7.jar(;;;;;;!META-INF/MANIFEST.MF)] (Duplicate zip entry [support-v4-r7.jar:android/support/v4/app/ActivityCompat.class]))
In my gradle file for the library I have the following as well well:
compile 'com.android.support:support-v4:22+'
compile 'com.jakewharton:disklrucache:2.0.2'
Hi,
Gave Sample a try on two Samsung Gingerbread phones got this exception after a while of scrolling grid up and down, have you considered using own thread pool instead of AsyncTasks?
Android 2.3.3 on GT-I9000 (Galaxy S)
02-21 03:23:46.320: ERROR/AndroidRuntime(7965): FATAL EXCEPTION: main
java.util.concurrent.RejectedExecutionException
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1876)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:774)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1295)
at android.os.AsyncTask.execute(AsyncTask.java:394)
at uk.co.senab.bitmapcache.samples.NetworkedCacheableImageView.loadImage(NetworkedCacheableImageView.java:158)
at uk.co.senab.bitmapcache.samples.PugListAdapter.getView(PugListAdapter.java:61)
at android.widget.AbsListView.obtainView(AbsListView.java:1933)
at android.widget.GridView.makeAndAddView(GridView.java:1219)
at android.widget.GridView.makeRow(GridView.java:265)
at android.widget.GridView.fillUp(GridView.java:303)
at android.widget.GridView.fillGap(GridView.java:196)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:3992)
at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:3437)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
at dalvik.system.NativeStart.main(Native Method)
Android 2.3.6 on SPH-M820-BST (Prevail)
02-20 18:19:51.625: ERROR/AndroidRuntime(11323): FATAL EXCEPTION: main
java.util.concurrent.RejectedExecutionException: pool=128/128, queue=10/10
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1961)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:794)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1315)
at android.os.AsyncTask.execute(AsyncTask.java:394)
at uk.co.senab.bitmapcache.samples.NetworkedCacheableImageView.loadImage(NetworkedCacheableImageView.java:158)
at uk.co.senab.bitmapcache.samples.PugListAdapter.getView(PugListAdapter.java:61)
at android.widget.AbsListView.obtainView(AbsListView.java:1533)
at android.widget.GridView.makeAndAddView(GridView.java:1269)
at android.widget.GridView.makeRow(GridView.java:315)
at android.widget.GridView.fillUp(GridView.java:353)
at android.widget.GridView.fillGap(GridView.java:246)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4142)
at android.widget.AbsListView$TwFlingRunnable.run(AbsListView.java:3370)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
Add the following method to the BitmapLruCache class:
public void purgeDiskCache() {
try {
mDiskCache.delete();
} catch (IOException ex) {
ex.printStackTrace();
}
}
The Gradle build
compile 'com.github.chrisbanes.bitmapcache:library:2.3'
will cause inclusion of support-v4 from maven-central
http://mvnrepository.com/artifact/com.google.android/support-v4/r7
This is an ancient release from 2012. The new releases are in android-sdk downloaded and updated via SDK manager. They appear to not be in maven central.
In my particular case I lost access to the class ViewCompat after including the bitmap-cache library via gradle (using compile 'com.github.chrisbanes.bitmapcache:library:2.3').
I think it will be a build problem if the gradle build forces inclusion of a particular version of the support lib, including if it forces newest version via '+'. I'm no Gradle 'expert' but it seems others have solved the problem of dependencies eg. me.henrytao:mdcore:1.2.0 (or I just havn't run into problems there yet).
Best Alex
PS: Seems to be awesome library though, thank you for sharing.
Native jar libraries can be used in the Mono development environment by creating a binding C# project.
However, the binding process strips out parameter names and the resultant bindings do sometimes need to be tinkered with. For example, Java integer enums can be wrapped into a C# enum type.
It would be nice if this project provided a C# project (or just a dll?) that Mono Android developers could drop into their apps and use.
I have this piece of code to init image cache
final BitmapLruCache.Builder builder = new BitmapLruCache.Builder(context.getApplicationContext());
builder.setMemoryCacheEnabled(true).setMemoryCacheMaxSizeUsingHeapSize();
builder.setDiskCacheEnabled(true).setDiskCacheLocation(cacheLocation)
.setRecyclePolicy(RecyclePolicy.DISABLED);
this.imageCache = builder.build();
Sometimes it fails at the last line which I think is wrong. It should just gracefully disable SD caching if the error is caught
Here's stack trace
java.lang.IllegalArgumentException: Disk Cache Location is not write-able
at uk.co.senab.bitmapcache.BitmapLruCache$Builder.isValidOptionsForDiskCache(BitmapLruCache.java:737)
at uk.co.senab.bitmapcache.BitmapLruCache$Builder.build(BitmapLruCache.java:614)
on my app I sometimes get this exception :
java.lang.IllegalArgumentException: Cannot draw recycled bitmaps
at android.view.GLES20Canvas.drawBitmap(GLES20Canvas.java:789)
at android.view.GLES20RecordingCanvas.drawBitmap(GLES20RecordingCanvas.java:118)
at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:393)
at android.widget.ImageView.onDraw(ImageView.java:985)
at android.view.View.draw(View.java:13712)
at android.view.View.getDisplayList(View.java:12650)
at android.view.View.getDisplayList(View.java:12694)
at android.view.View.draw(View.java:13428)
at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
at android.view.View.getDisplayList(View.java:12648)
at android.view.View.getDisplayList(View.java:12694)
at android.view.View.draw(View.java:13428)
at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
at android.widget.AbsListView.dispatchDraw(AbsListView.java:2327)
at android.view.View.draw(View.java:13715)
at android.widget.AbsListView.draw(AbsListView.java:3653)
at android.view.View.getDisplayList(View.java:12650)
at android.view.View.getDisplayList(View.java:12694)
at android.view.View.draw(View.java:13428)
at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
at android.view.View.getDisplayList(View.java:12648)
at android.view.View.getDisplayList(View.java:12694)
at android.view.View.draw(View.java:13428)
at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
at android.view.View.getDisplayList(View.java:12648)
at android.view.View.getDisplayList(View.java:12694)
at android.view.View.draw(View.java:13428)
at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
at android.view.View.getDisplayList(View.java:12648)
at android.view.View.getDisplayList(View.java:12694)
at android.view.View.draw(View.java:13428)
at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
at android.view.View.draw(View.java:13715)
at android.widget.FrameLayout.draw(FrameLayout.java:467)
at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2211)
at android.view.View.getDisplayList(View.java:12650)
at android.view.View.getDisplayList(View.java:12694)
at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1198)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2173)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2045)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1854)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
at android.view.Choreographer.doCallbacks(Choreographer.java:562)
at android.view.Choreographer.doFrame(Choreographer.java:532)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
I was writing an app that has quite a lot of images that sometimes they are shown as thumbnails and sometimes as big picture. My server gives me only big pictures. So I thought that I will use that lib as ultimate cache image for my app so I wouldn't have to worry ever about deleting not used image files, but I stuck with a problem.
How to add some file to cache and then take bitmap with different resolution. Am I missing some easy solution of doing that or it's not designed that way?
In BitmapMemoryLruCache#getBitmapFromRemoved method, we judge if the bitmap is used by following:
value != null && value.isBitmapValid() && value.isBitmapMutable()
This is not enough and should be added following:
&& !value.isBeingDisplayed() && !value.isReferencedByCache()
This is because LruCache#entryRemoved is not called on the bitmap is no more used but called on the last method call of LruCache#get for the bitmap is in the distant past.
I met this issue when using ListView on ViewPager. When I scrolled ListView enough and changed page, bitmaps on another pages are not correct.
containsInDiskCache()
method is not transforming the URL to make it compatible with DiskLruCache
. This causes exceptions if one tries to lookup contains(url)
with disk cache enabled.
Sometimes I get an IllegalStateException
when calling BitmapLruCache.getFromDiskCache()
. I have both a disk and memory cache configured, and this call is successful most of the time.
Here's the stacktrace:
java.lang.IllegalStateException: uk.co.senab.bitmapcache.BitmapMemoryLruCache.sizeOf() is reporting inconsistent results!
at android.support.v4.util.LruCache.trimToSize
at android.support.v4.util.LruCache.put
at uk.co.senab.bitmapcache.BitmapMemoryLruCache.put
at uk.co.senab.bitmapcache.BitmapLruCache.getFromDiskCache
Using GridViewActivity in sample I get OutOfMemoryError on Android x86 2.3.3 emulator.
03-14 02:38:35.933: ERROR/AndroidRuntime(1322): FATAL EXCEPTION: AsyncTask #7
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:200)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
at java.lang.Thread.run(Thread.java:1019)
Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:470)
at uk.co.senab.bitmapcache.BitmapLruCache.getFromDiskCache(BitmapLruCache.java:262)
at uk.co.senab.bitmapcache.BitmapLruCache.get(BitmapLruCache.java:233)
at uk.co.senab.bitmapcache.samples.NetworkedCacheableImageView$ImageUrlAsyncTask.doInBackground(NetworkedCacheableImageView.java:81)
at uk.co.senab.bitmapcache.samples.NetworkedCacheableImageView$ImageUrlAsyncTask.doInBackground(NetworkedCacheableImageView.java:54)
at android.os.AsyncTask$2.call(AsyncTask.java:185)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
... 4 more
I've got a recycled bitmap issue cropping up when using a TransitionDrawable. I'm seeing this pretty consistently on an HTC Desire HD running 2.3.3, and sporadically on other devices. I'm using version 2.3 and the cache is configured for memory only.
I am able to get work around the issue by manually calling cbd.setBeingUsed(true); after pulling the bitmap from the cache, like so (and yes, mImageView is an instance of CacheableImageView):
private void animate() {
if (mImageView == null) { Log.w(TAG,"Null imageview?"); return; }
if (this.isDetached()) { Log.w(TAG,"Attempting animation on detached fragment."); return; }
int imageIndex = getNextIndex();
currentIndex = imageIndex;
String index = String.valueOf(images[imageIndex]);
CacheableBitmapDrawable cbd = null;
if (mCache.contains(index)) {
cbd = mCache.get(index);
}
if (cbd == null || !cbd.isBitmapValid()) {
cbd = mCache.put(index, BitmapFactory.decodeResource(getResources(), images[imageIndex]));
}
// without this, I get sporadic recycled bitmap errors!
cbd.setBeingUsed(true);
Drawable[] drawables = new Drawable[2];
drawables[0] = mImageView.getDrawable();
drawables[1] = cbd;
TransitionDrawable transitionDrawable = new TransitionDrawable(drawables);
transitionDrawable.setCrossFadeEnabled(true);
mImageView.setImageDrawable(transitionDrawable);
transitionDrawable.startTransition(2000);
}
The stack trace is:
java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@40644e28 at
android.graphics.Canvas.throwIfRecycled(Canvas.java:973) at
android.graphics.Canvas.drawBitmap(Canvas.java:1062) at
android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:325) at
uk.co.senab.bitmapcache.CacheableBitmapDrawable.draw(CacheableBitmapDrawable.java:77) at
android.graphics.drawable.TransitionDrawable.draw(TransitionDrawable.java:204) at
android.graphics.drawable.TransitionDrawable.draw(TransitionDrawable.java:196) at
android.graphics.drawable.TransitionDrawable.draw(TransitionDrawable.java:196) at
android.widget.ImageView.onDraw(ImageView.java:935) at
android.view.View.draw(View.java:6971) at
android.view.ViewGroup.drawChild(ViewGroup.java:1710) at
android.view.ViewGroup.dispatchDraw(ViewGroup.java:1437) at
android.view.ViewGroup.drawChild(ViewGroup.java:1708) at
android.view.ViewGroup.dispatchDraw(ViewGroup.java:1437) at
android.view.View.draw(View.java:6974) at
android.view.ViewGroup.drawChild(ViewGroup.java:1710) at
android.view.ViewGroup.dispatchDraw(ViewGroup.java:1437) at
android.view.ViewGroup.drawChild(ViewGroup.java:1708) at
android.view.ViewGroup.dispatchDraw(ViewGroup.java:1437) at
android.view.View.draw(View.java:6974) at
android.support.v4.view.ViewPager.draw(ViewPager.java:2157) at
android.view.ViewGroup.drawChild(ViewGroup.java:1710) at
android.view.ViewGroup.dispatchDraw(ViewGroup.java:1437) at
android.view.ViewGroup.drawChild(ViewGroup.java:1708) at
android.view.ViewGroup.dispatchDraw(ViewGroup.java:1437) at
android.view.View.draw(View.java:6974) at
android.widget.FrameLayout.draw(FrameLayout.java:357) at
android.view.ViewGroup.drawChild(ViewGroup.java:1710) at
android.view.ViewGroup.dispatchDraw(ViewGroup.java:1437) at
android.view.ViewGroup.drawChild(ViewGroup.java:1708) at
android.view.ViewGroup.dispatchDraw(ViewGroup.java:1437) at
android.view.ViewGroup.drawChild(ViewGroup.java:1708) at
android.view.ViewGroup.dispatchDraw(ViewGroup.java:1437) at
android.view.View.draw(View.java:6974) at
android.widget.FrameLayout.draw(FrameLayout.java:357) at
com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1929) at
android.view.ViewRoot.draw(ViewRoot.java:1590) at
android.view.ViewRoot.performTraversals(ViewRoot.java:1290) at
android.view.ViewRoot.handleMessage(ViewRoot.java:1939) at
android.os.Handler.dispatchMessage(Handler.java:99) at
android.os.Looper.loop(Looper.java:143) at
android.app.ActivityThread.main(ActivityThread.java:4196) at
java.lang.reflect.Method.invokeNative(Native Method) at
java.lang.reflect.Method.invoke(Method.java:507) at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) at
dalvik.system.NativeStart.main(Native Method)
08-18 17:03:11.143: W/System.err(9568): com.facebook.android.DialogError: Couldn't connect to the server.
08-18 17:03:11.153: W/System.err(9568): at com.facebook.android.FbDialog$FbWebViewClient.onReceivedError(FbDialog.java:147)
08-18 17:03:11.153: W/System.err(9568): at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:431)
08-18 17:03:11.153: W/System.err(9568): at android.os.Handler.dispatchMessage(Handler.java:99)
08-18 17:03:11.153: W/System.err(9568): at android.os.Looper.loop(Looper.java:137)
08-18 17:03:11.158: W/System.err(9568): at android.app.ActivityThread.main(ActivityThread.java:4921)
08-18 17:03:11.158: W/System.err(9568): at java.lang.reflect.Method.invokeNative(Native Method)
08-18 17:03:11.158: W/System.err(9568): at java.lang.reflect.Method.invoke(Method.java:511)
08-18 17:03:11.158: W/System.err(9568): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
08-18 17:03:11.158: W/System.err(9568): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
08-18 17:03:11.163: W/System.err(9568): at dalvik.system.NativeStart.main(Native Method)
The error message returned is unsupported bitmap configuration: null
I suggest to replace current onDetachFromWindow with
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
onDrawableUnset(getDrawable());
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
onDrawableSet(getDrawable());
}
I had an issue earlier which caused me to disable using CacheableBitmapDrawable in favor of ImageView. I have now tested again with CacheableBitmapDrawable but could not reproduce problem (probably my usage has changed). However my memory told me the problem probably came from nulling. Hence the above change, which I deem healthy.
Is there a sample app using ListView/GridView
?
The problem is that I adapted your sample for ViewPager
but I keep getting errors because bitmaps that are in cache are being recycled too early and therefore I keep getting errors - possible because of reusing and ViewHolder pattern
in ListView
?
If I start the app first time - everything is working, I close the activity and app (back button), re-open and none of the images is displayed (tries to use all those already recycled views).
Till then I'll probably stick with Android Guide on Bitmaps caching but would like to know the solution.
Thanks.
I'm trying to implement an infinite ViewPager that downloads images and displays each in its own instance of a Fragment I have created, using the CacheableImageView to hold the bitmap in the Fragment.
I think this error has something to do with the ViewPager destroying views when they are no longer visible.
06-22 16:44:57.198: W/System.err(25969): java.lang.Throwable: Recycled Bitmap Method Stack
06-22 16:44:57.198: W/System.err(25969): at uk.co.senab.bitmapcache.CacheableBitmapDrawable.checkState(CacheableBitmapDrawable.java:208)
06-22 16:44:57.198: W/System.err(25969): at uk.co.senab.bitmapcache.CacheableBitmapDrawable.access$000(CacheableBitmapDrawable.java:27)
06-22 16:44:57.206: W/System.err(25969): at uk.co.senab.bitmapcache.CacheableBitmapDrawable$CheckStateRunnable.run(CacheableBitmapDrawable.java:239)
06-22 16:44:57.206: W/System.err(25969): at uk.co.senab.bitmapcache.CacheableBitmapDrawable$CheckStateRunnable.run(CacheableBitmapDrawable.java:230)
06-22 16:44:57.206: W/System.err(25969): at uk.co.senab.bitmapcache.WeakReferenceRunnable.run(WeakReferenceRunnable.java:33)
06-22 16:44:57.214: W/System.err(25969): at android.os.Handler.handleCallback(Handler.java:615)
06-22 16:44:57.214: W/System.err(25969): at android.os.Handler.dispatchMessage(Handler.java:92)
06-22 16:44:57.214: W/System.err(25969): at android.os.Looper.loop(Looper.java:137)
06-22 16:44:57.214: W/System.err(25969): at android.app.ActivityThread.main(ActivityThread.java:4895)
06-22 16:44:57.222: W/System.err(25969): at java.lang.reflect.Method.invokeNative(Native Method)
06-22 16:44:57.222: W/System.err(25969): at java.lang.reflect.Method.invoke(Method.java:511)
06-22 16:44:57.222: W/System.err(25969): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994)
06-22 16:44:57.222: W/System.err(25969): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761)
06-22 16:44:57.222: W/System.err(25969): at dalvik.system.NativeStart.main(Native Method)
06-22 16:44:57.230: W/System.err(25969): java.lang.IllegalArgumentException: Cannot draw recycled bitmaps
06-22 16:44:57.261: W/System.err(25969): at android.view.GLES20Canvas.drawBitmap(GLES20Canvas.java:778)
06-22 16:44:57.261: W/System.err(25969): at android.view.GLES20RecordingCanvas.drawBitmap(GLES20RecordingCanvas.java:117)
06-22 16:44:57.269: W/System.err(25969): at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:393)
06-22 16:44:57.269: W/System.err(25969): at uk.co.senab.bitmapcache.CacheableBitmapDrawable.draw(CacheableBitmapDrawable.java:70)
06-22 16:44:57.269: W/System.err(25969): at android.widget.ImageView.onDraw(ImageView.java:979)
06-22 16:44:57.269: W/System.err(25969): at android.view.View.draw(View.java:13765)
06-22 16:44:57.269: W/System.err(25969): at android.view.View.getDisplayList(View.java:12716)
06-22 16:44:57.277: W/System.err(25969): at android.view.View.getDisplayList(View.java:12760)
06-22 16:44:57.277: W/System.err(25969): at android.view.View.draw(View.java:13489)
06-22 16:44:57.277: W/System.err(25969): at android.view.ViewGroup.drawChild(ViewGroup.java:2938)
06-22 16:44:57.277: W/System.err(25969): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2808)
06-22 16:44:57.277: W/System.err(25969): at android.view.View.getDisplayList(View.java:12714)
06-22 16:44:57.277: W/System.err(25969): at android.view.View.getDisplayList(View.java:12760)
06-22 16:44:57.284: W/System.err(25969): at android.view.View.draw(View.java:13489)
06-22 16:44:57.284: W/System.err(25969): at android.view.ViewGroup.drawChild(ViewGroup.java:2938)
06-22 16:44:57.284: W/System.err(25969): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2808)
06-22 16:44:57.284: W/System.err(25969): at android.view.View.getDisplayList(View.java:12714)
06-22 16:44:57.284: W/System.err(25969): at android.view.View.getDisplayList(View.java:12760)
06-22 16:44:57.284: W/System.err(25969): at android.view.View.draw(View.java:13489)
06-22 16:44:57.292: W/System.err(25969): at android.view.ViewGroup.drawChild(ViewGroup.java:2938)
06-22 16:44:57.292: W/System.err(25969): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2808)
06-22 16:44:57.292: W/System.err(25969): at android.view.View.draw(View.java:13768)
06-22 16:44:57.292: W/System.err(25969): at android.support.v4.view.ViewPager.draw(ViewPager.java:2153)
06-22 16:44:57.292: W/System.err(25969): at android.view.View.getDisplayList(View.java:12716)
06-22 16:44:57.300: W/System.err(25969): at android.view.View.getDisplayList(View.java:12760)
06-22 16:44:57.300: W/System.err(25969): at android.view.View.draw(View.java:13489)
06-22 16:44:57.300: W/System.err(25969): at android.view.ViewGroup.drawChild(ViewGroup.java:2938)
06-22 16:44:57.300: W/System.err(25969): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2808)
06-22 16:44:57.300: W/System.err(25969): at android.view.View.getDisplayList(View.java:12714)
06-22 16:44:57.300: W/System.err(25969): at android.view.View.getDisplayList(View.java:12760)
06-22 16:44:57.308: W/System.err(25969): at android.view.View.draw(View.java:13489)
06-22 16:44:57.308: W/System.err(25969): at android.view.ViewGroup.drawChild(ViewGroup.java:2938)
06-22 16:44:57.308: W/System.err(25969): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2808)
06-22 16:44:57.308: W/System.err(25969): at android.view.View.draw(View.java:13768)
06-22 16:44:57.308: W/System.err(25969): at android.widget.FrameLayout.draw(FrameLayout.java:467)
06-22 16:44:57.316: W/System.err(25969): at android.view.View.getDisplayList(View.java:12716)
06-22 16:44:57.316: W/System.err(25969): at android.view.View.getDisplayList(View.java:12760)
06-22 16:44:57.323: W/System.err(25969): at android.view.View.draw(View.java:13489)
06-22 16:44:57.323: W/System.err(25969): at android.view.ViewGroup.drawChild(ViewGroup.java:2938)
06-22 16:44:57.323: W/System.err(25969): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2808)
06-22 16:44:57.323: W/System.err(25969): at android.view.View.getDisplayList(View.java:12714)
06-22 16:44:57.323: W/System.err(25969): at android.view.View.getDisplayList(View.java:12760)
06-22 16:44:57.331: W/System.err(25969): at android.view.View.draw(View.java:13489)
06-22 16:44:57.331: W/System.err(25969): at android.view.ViewGroup.drawChild(ViewGroup.java:2938)
06-22 16:44:57.331: W/System.err(25969): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2808)
06-22 16:44:57.331: W/System.err(25969): at android.view.View.draw(View.java:13768)
06-22 16:44:57.331: W/System.err(25969): at android.widget.FrameLayout.draw(FrameLayout.java:467)
06-22 16:44:57.331: W/System.err(25969): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2394)
06-22 16:44:57.339: W/System.err(25969): at android.view.View.getDisplayList(View.java:12716)
06-22 16:44:57.339: W/System.err(25969): at android.view.View.getDisplayList(View.java:12760)
06-22 16:44:57.339: W/System.err(25969): at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1144)
06-22 16:44:57.339: W/System.err(25969): at android.view.ViewRootImpl.draw(ViewRootImpl.java:2265)
06-22 16:44:57.339: W/System.err(25969): at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2137)
06-22 16:44:57.339: W/System.err(25969): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1948)
06-22 16:44:57.347: W/System.err(25969): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1105)
06-22 16:44:57.347: W/System.err(25969): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4462)
06-22 16:44:57.347: W/System.err(25969): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
06-22 16:44:57.347: W/System.err(25969): at android.view.Choreographer.doCallbacks(Choreographer.java:555)
06-22 16:44:57.347: W/System.err(25969): at android.view.Choreographer.doFrame(Choreographer.java:525)
06-22 16:44:57.347: W/System.err(25969): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
06-22 16:44:57.347: W/System.err(25969): at android.os.Handler.handleCallback(Handler.java:615)
06-22 16:44:57.355: W/System.err(25969): at android.os.Handler.dispatchMessage(Handler.java:92)
06-22 16:44:57.355: W/System.err(25969): at android.os.Looper.loop(Looper.java:137)
06-22 16:44:57.355: W/System.err(25969): at android.app.ActivityThread.main(ActivityThread.java:4895)
06-22 16:44:57.355: W/System.err(25969): at java.lang.reflect.Method.invokeNative(Native Method)
06-22 16:44:57.355: W/System.err(25969): at java.lang.reflect.Method.invoke(Method.java:511)
06-22 16:44:57.355: W/System.err(25969): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994)
06-22 16:44:57.355: W/System.err(25969): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761)
06-22 16:44:57.362: W/System.err(25969): at dalvik.system.NativeStart.main(Native Method)
Since I'm not forcing recycle() anywhere in my code I assume that it is BitmapCache that is responsible
Here's the full stack trace
java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@406c13e8
at android.graphics.Canvas.throwIfRecycled(Canvas.java:965)
at android.graphics.Canvas.drawBitmap(Canvas.java:1054)
at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:325)
at android.widget.ImageView.onDraw(ImageView.java:854)
at android.view.View.draw(View.java:6889)
at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.widget.AbsListView.dispatchDraw(AbsListView.java:1485)
at android.widget.ListView.dispatchDraw(ListView.java:3138)
at android.view.View.draw(View.java:7011)
at android.widget.AbsListView.draw(AbsListView.java:2593)
at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.View.draw(View.java:6892)
at android.widget.FrameLayout.draw(FrameLayout.java:357)
at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at com.slidingmenu.lib.CustomViewAbove.dispatchDraw(CustomViewAbove.java:845)
at android.view.View.draw(View.java:6892)
at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.View.draw(View.java:6892)
at android.widget.FrameLayout.draw(FrameLayout.java:357)
at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.View.draw(View.java:6892)
at android.widget.FrameLayout.draw(FrameLayout.java:357)
at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1895)
at android.view.ViewRoot.draw(ViewRoot.java:1524)
at android.view.ViewRoot.performTraversals(ViewRoot.java:1260)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1864)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3695)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)
at dalvik.system.NativeStart.main(Native Method)
java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@406d7170
at android.graphics.Canvas.throwIfRecycled(Canvas.java:965)
at android.graphics.Canvas.drawBitmap(Canvas.java:1054)
at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:325)
at android.widget.ImageView.onDraw(ImageView.java:854)
at android.view.View.draw(View.java:6889)
at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.widget.AbsListView.dispatchDraw(AbsListView.java:1485)
at android.widget.ListView.dispatchDraw(ListView.java:3138)
at android.view.View.draw(View.java:7011)
at android.widget.AbsListView.draw(AbsListView.java:2593)
at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.View.draw(View.java:6892)
at android.widget.FrameLayout.draw(FrameLayout.java:357)
at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at com.slidingmenu.lib.CustomViewAbove.dispatchDraw(CustomViewAbove.java:845)
at android.view.View.draw(View.java:6892)
at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.View.draw(View.java:6892)
at android.widget.FrameLayout.draw(FrameLayout.java:357)
at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
at android.view.View.draw(View.java:6892)
at android.widget.FrameLayout.draw(FrameLayout.java:357)
at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1895)
at android.view.ViewRoot.draw(ViewRoot.java:1524)
at android.view.ViewRoot.performTraversals(ViewRoot.java:1260)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1864)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3695)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)
at dalvik.system.NativeStart.main(Native Method)
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856) Caused by: java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:527)
at uk.co.senab.bitmapcache.BitmapLruCache.decodeBitmap(BitmapLruCache.java:578)
at uk.co.senab.bitmapcache.BitmapLruCache.getFromDiskCache(BitmapLruCache.java:272)
Seeing an issue where when scrolling sometimes the images won't get displayed.
I put together a sample project that illustrates the problem. If you scroll around enough you will see the issue happen.
https://docs.google.com/file/d/0BwhkatesjXP7dTRJWnZkbnBrc1E/edit?usp=sharing
More details about the problem here:
http://stackoverflow.com/questions/15839626/listview-items-with-animation-do-not-render-properly
First of all thanks for the library. I use CacheableImageView and I think there is unexpected behavior.
To reproduce:
After this I have get:
04-23 16:36:05.401: E/AndroidRuntime(4435): FATAL EXCEPTION: main
04-23 16:36:05.401: E/AndroidRuntime(4435): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@4056fa50
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.graphics.Canvas.throwIfRecycled(Canvas.java:973)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.graphics.Canvas.drawBitmap(Canvas.java:1062)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:325)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.widget.ImageView.onDraw(ImageView.java:935)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.view.View.draw(View.java:6970)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.view.ViewGroup.drawChild(ViewGroup.java:1732)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1459)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.view.ViewGroup.drawChild(ViewGroup.java:1730)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1459)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.view.ViewGroup.drawChild(ViewGroup.java:1730)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1459)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.view.View.draw(View.java:6973)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.widget.FrameLayout.draw(FrameLayout.java:357)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.view.ViewGroup.drawChild(ViewGroup.java:1732)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1459)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.view.ViewGroup.drawChild(ViewGroup.java:1730)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1459)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.view.ViewGroup.drawChild(ViewGroup.java:1730)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1459)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.view.View.draw(View.java:6973)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.widget.FrameLayout.draw(FrameLayout.java:357)
04-23 16:36:05.401: E/AndroidRuntime(4435): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1997)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.view.ViewRoot.draw(ViewRoot.java:1600)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.view.ViewRoot.performTraversals(ViewRoot.java:1321)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.view.ViewRoot.handleMessage(ViewRoot.java:1957)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.os.Handler.dispatchMessage(Handler.java:99)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.os.Looper.loop(Looper.java:150)
04-23 16:36:05.401: E/AndroidRuntime(4435): at android.app.ActivityThread.main(ActivityThread.java:4277)
04-23 16:36:05.401: E/AndroidRuntime(4435): at java.lang.reflect.Method.invokeNative(Native Method)
04-23 16:36:05.401: E/AndroidRuntime(4435): at java.lang.reflect.Method.invoke(Method.java:507)
04-23 16:36:05.401: E/AndroidRuntime(4435): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
04-23 16:36:05.401: E/AndroidRuntime(4435): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
04-23 16:36:05.401: E/AndroidRuntime(4435): at dalvik.system.NativeStart.main(Native Method)
If before setImageBitmap I cache my bitmap I can't even set it because of this error is happened when I try to set a cached bitmap.
I think there's a race condition here.
This code calls setImageDrawable() before the reference count is incremented by setBeingUsed(). The race is that if the drawable is evicted from the cache due to memory pressure after the drawable is assigned but before the reference count is incremented then checkState() might be called from another thread, and the bitmap might be recycled, leading to the "Canvas trying to use a recycled bitmap" exception.
I am getting the following NPE:
Android-BitmapCache v2.1
02-18 00:18:53.701: E/AndroidRuntime(15150): FATAL EXCEPTION: AsyncTask #2
02-18 00:18:53.701: E/AndroidRuntime(15150): java.lang.RuntimeException: An error occured while executing doInBackground()
02-18 00:18:53.701: E/AndroidRuntime(15150): at android.os.AsyncTask$3.done(AsyncTask.java:200)
02-18 00:18:53.701: E/AndroidRuntime(15150): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
02-18 00:18:53.701: E/AndroidRuntime(15150): at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
02-18 00:18:53.701: E/AndroidRuntime(15150): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
02-18 00:18:53.701: E/AndroidRuntime(15150): at java.util.concurrent.FutureTask.run(FutureTask.java:138)
02-18 00:18:53.701: E/AndroidRuntime(15150): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
02-18 00:18:53.701: E/AndroidRuntime(15150): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
02-18 00:18:53.701: E/AndroidRuntime(15150): at java.lang.Thread.run(Thread.java:1019)
02-18 00:18:53.701: E/AndroidRuntime(15150): Caused by: java.lang.NullPointerException
02-18 00:18:53.701: E/AndroidRuntime(15150): at uk.co.senab.bitmapcache.BitmapLruCache.getFromDiskCache(BitmapLruCache.java:225)
02-18 00:18:53.701: E/AndroidRuntime(15150): at uk.co.senab.bitmapcache.BitmapLruCache.get(BitmapLruCache.java:189)
02-18 00:18:53.701: E/AndroidRuntime(15150): at uk.co.senab.bitmapcache.BitmapLruCache.get(BitmapLruCache.java:167)
02-18 00:18:53.701: E/AndroidRuntime(15150): at org.thomasamsler.android.polling.service.ImageService$DownloadImageTask.doInBackground(ImageService.java:195)
02-18 00:18:53.701: E/AndroidRuntime(15150): at org.thomasamsler.android.polling.service.ImageService$DownloadImageTask.doInBackground(ImageService.java:1)
02-18 00:18:53.701: E/AndroidRuntime(15150): at android.os.AsyncTask$2.call(AsyncTask.java:185)
02-18 00:18:53.701: E/AndroidRuntime(15150): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
02-18 00:18:53.701: E/AndroidRuntime(15150): ... 4 more
When the library and the sample are imported into my Eclipse, NoClassDefFoundError occurrd after the sample was runned, the log is below:
02-27 11:15:38.049: E/AndroidRuntime(19734): FATAL EXCEPTION: main
02-27 11:15:38.049: E/AndroidRuntime(19734): java.lang.NoClassDefFoundError: uk.co.senab.bitmapcache.BitmapMemoryLruCache
02-27 11:15:38.049: E/AndroidRuntime(19734): at uk.co.senab.bitmapcache.BitmapLruCache$Builder.build(BitmapLruCache.java:700)
02-27 11:15:38.049: E/AndroidRuntime(19734): at uk.co.senab.bitmapcache.samples.SampleApplication.onCreate(SampleApplication.java:52)
02-27 11:15:38.049: E/AndroidRuntime(19734): at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:973)
02-27 11:15:38.049: E/AndroidRuntime(19734): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3971)
02-27 11:15:38.049: E/AndroidRuntime(19734): at android.app.ActivityThread.access$1300(ActivityThread.java:128)
02-27 11:15:38.049: E/AndroidRuntime(19734): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1199)
02-27 11:15:38.049: E/AndroidRuntime(19734): at android.os.Handler.dispatchMessage(Handler.java:99)
02-27 11:15:38.049: E/AndroidRuntime(19734): at android.os.Looper.loop(Looper.java:137)
02-27 11:15:38.049: E/AndroidRuntime(19734): at android.app.ActivityThread.main(ActivityThread.java:4517)
02-27 11:15:38.049: E/AndroidRuntime(19734): at java.lang.reflect.Method.invokeNative(Native Method)
02-27 11:15:38.049: E/AndroidRuntime(19734): at java.lang.reflect.Method.invoke(Method.java:511)
02-27 11:15:38.049: E/AndroidRuntime(19734): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
02-27 11:15:38.049: E/AndroidRuntime(19734): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
02-27 11:15:38.049: E/AndroidRuntime(19734): at dalvik.system.NativeStart.main(Native Method)
Could you help me check this why?
It appears to be attempting to use com.jakewharton.DiskLruCache, but this is now com.jakewharton.disklrucache.DiskLruCache in DiskLruCache 2.0
The README link http://bit.ly/android-bitmapcache-jar doesn't contain the latest jar. It's possible to get the jar from the maven repository, but I just wanted to make sure you knew.
I noticed that put seems to be pretty slow. So I did some tests:
53ms Connecting
525ms Downloading image
39ms Resizing image
191ms Saving resized image to sd card (manually)
969ms Put into cache (Android-BitmapCache)
So currently I am wondering WHAT is taking so long in the put method? It can't be saving the image to the SD card, since that only takes less than 1/4 of that time.
Any Ideas why that could be and how I could speed this up?
As well I looked at the speed when getting the image:
119ms Get image from cache (Android-BitmapCache)
80ms Decode bitmap from file manually
So I wonder what is taking those 40 additional milliseconds when getting the image.
Sorry for being so picky :). But this speed problem is currently the only reason why I am considering to writing my own cache. But I hope we can get this run faster :)
The DiskLruCache package name changed to com.jakewharton.disklrucache
in v2.0. This needs to be updated in order to use the latest version.
The README
indicates that a sample app is available "from the Downloads tab above". However, GitHub (in their infinite wisdom) eliminated the Downloads tab and is eliminating downloads entirely in a few months, so we cannot download your sample app.
@chrisbanes has not updated repository for 2 years, so I would say its dead.
farfromrefug (https://github.com/Akylas/Android-BitmapCache/) made lots of updates in 2014 that was never pulled. I pushed my changes to farfromrefug(Akylas) but those have not yet been accepted. So today this is the most update version of the repository, I believe (as I pulled from farfromrefug):
https://github.com/arberg/Android-BitmapCache/
That means checkout the repository and include source-files and don't use the gradle/maven release.
The library uses an image Url as the source of a bitmap (and to identify a bitmap uniquely). Can this be used with "local" bitmaps (i.e., those decoded from file/resources)?
E/BitmapCache(20110): Unable to decode stream
E/BitmapCache(20110): java.lang.IllegalArgumentException: Problem decoding into
existing bitmap
E/BitmapCache(20110): at android.graphics.BitmapFactory.decodeStream(BitmapFac
tory.java:537)
E/BitmapCache(20110): at uk.co.senab.bitmapcache.BitmapLruCache.decodeBitmap(B
itmapLruCache.java:578)
E/BitmapCache(20110): at uk.co.senab.bitmapcache.BitmapLruCache.getFromDiskCac
he(BitmapLruCache.java:272)
E/BitmapCache(20110): at uk.co.senab.bitmapcache.BitmapLruCache.get(BitmapLruC
ache.java:245)
E/BitmapCache(20110): at uk.co.senab.bitmapcache.samples.NetworkedCacheableIma
geView$ImageUrlAsyncTask.doInBackground(NetworkedCacheableImageView.java:86)
E/BitmapCache(20110): at uk.co.senab.bitmapcache.samples.NetworkedCacheableIma
geView$ImageUrlAsyncTask.doInBackground(NetworkedCacheableImageView.java:57)
E/BitmapCache(20110): at android.os.AsyncTask$2.call(AsyncTask.java:287)
E/BitmapCache(20110): at java.util.concurrent.FutureTask$Sync.innerRun(FutureT
ask.java:305)
E/BitmapCache(20110): at java.util.concurrent.FutureTask.run(FutureTask.java:1
37)
E/BitmapCache(20110): at java.util.concurrent.ThreadPoolExecutor.runWorker(Thr
eadPoolExecutor.java:1076)
E/BitmapCache(20110): at java.util.concurrent.ThreadPoolExecutor$Worker.run(Th
readPoolExecutor.java:569)
E/BitmapCache(20110): at java.lang.Thread.run(Thread.java:856)
As in topic CacheableImageView should have constructor like:
public CacheableImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.