microsoftarchive / android-sliding-layer-lib

Highly customizable SlidingLayer as you have seen in Wunderlist
http://wunderlist.com
Apache License 2.0
932 stars 277 forks source link

Random RunTime Error: canvas: trying to use a recycled bitmap #6

Open christianvina opened 11 years ago

christianvina commented 11 years ago

Hello,

I finally got runing the sliding layer on my app. It was an API level issue, i was using 4.2.... Using 4.1 the problem was solved...

Now my problem is that when i slide-in and slide-out the layer, i get a random runtime exception that indicates the following... Can you help me out?

java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@40db6420

04-23 12:49:59.658: E/AndroidRuntime(28582): at android.graphics.Canvas.throwIfRecycled(Canvas.java:1026) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.graphics.Canvas.drawBitmap(Canvas.java:1065) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.View.draw(View.java:13625) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.ViewGroup.drawChild(ViewGroup.java:2928) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.View.draw(View.java:13594) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.ViewGroup.drawChild(ViewGroup.java:2928) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.View.draw(View.java:13594) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.ViewGroup.drawChild(ViewGroup.java:2928) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.View.draw(View.java:13715) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.View.draw(View.java:13596) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.ViewGroup.drawChild(ViewGroup.java:2928) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.View.draw(View.java:13715) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.widget.FrameLayout.draw(FrameLayout.java:467) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.View.draw(View.java:13596) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.ViewGroup.drawChild(ViewGroup.java:2928) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.View.draw(View.java:13594) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.ViewGroup.drawChild(ViewGroup.java:2928) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.View.draw(View.java:13715) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.widget.FrameLayout.draw(FrameLayout.java:467) 04-23 12:49:59.658: E/AndroidRuntime(28582): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2211) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.ViewRootImpl.drawSoftware(ViewRootImpl.java:2281) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.ViewRootImpl.draw(ViewRootImpl.java:2177) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2045) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1854) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.Choreographer.doCallbacks(Choreographer.java:562) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.Choreographer.doFrame(Choreographer.java:532) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.os.Handler.handleCallback(Handler.java:725) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.os.Handler.dispatchMessage(Handler.java:92) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.os.Looper.loop(Looper.java:137) 04-23 12:49:59.658: E/AndroidRuntime(28582): at android.app.ActivityThread.main(ActivityThread.java:5041) 04-23 12:49:59.658: E/AndroidRuntime(28582): at java.lang.reflect.Method.invokeNative(Native Method) 04-23 12:49:59.658: E/AndroidRuntime(28582): at java.lang.reflect.Method.invoke(Method.java:511) 04-23 12:49:59.658: E/AndroidRuntime(28582): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 04-23 12:49:59.658: E/AndroidRuntime(28582): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 04-23 12:49:59.658: E/AndroidRuntime(28582): at dalvik.system.NativeStart.main(Native Method)

chrisjenx commented 11 years ago

Looking at the stack trace, nothing seems to lend its self to SlidingLayer to be causing this.

I'm assuming you have tried; removing the contents of the sliding layer (and the layer its self?) then checking that the project builds?

JlUgia commented 11 years ago

I bet it is something related to the contents you are putting in the SlidingLayer, that's why it brings problem when drawing (showing or hiding the view).

cingram-dev commented 11 years ago

Did you ever get this fixed? I'm having the same issue.

brunjo commented 11 years ago

I had the same problem with my own app and the sample app on Android 4.2.2 (API level 17). Then I tried it with Android 4.1.2 (API 16) and it worked perfectly.

czechooo commented 11 years ago

I have the same issue.

When contents of the Sliding Layer is just a simple, plain button then I get the error about using already recycled bitmap. When I put a text instead it works. Seems not many people can replicate it, must be some small, weird bug.

(API level 17, Android 4.2.2)

chrisjenx commented 11 years ago

Maybe check how your assigning the image to your button?

On 25 June 2013 09:05, czechooo notifications@github.com wrote:

I have the same issue.

When contents of the Sliding Layer is just a simple, plain button then I get the error about using already recycled bitmap. When I put a text instead it works. Seems not many people can replicate it, must be some small, weird bug.

(API level 17, Android 4.2.2)

— Reply to this email directly or view it on GitHubhttps://github.com/6wunderkinder/android-sliding-layer-lib/issues/6#issuecomment-19959367 .

czechooo commented 11 years ago

I was thinking that maybe some images associated with the button would be a problem here but I used the simplest one and still the same:

 <Button 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Test Button"/>

Can't you replicate it? Hmm that's interesting.

chrisjenx commented 11 years ago

I am yet to try, but I am using the library with a whole host of custom views, and I dont have an issue, which makes me think its limited to something in your app specifically. :(

On 25 June 2013 09:37, czechooo notifications@github.com wrote:

I was thinking that maybe some images associated with button would be a problem here but I used the simplest one and still the same: android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Test Button"/> Can't you replicate it? Hmm that's interesting.

— Reply to this email directly or view it on GitHubhttps://github.com/6wunderkinder/android-sliding-layer-lib/issues/6#issuecomment-19960774 .

czechooo commented 11 years ago

Sure no worries, just wondering if anybody else had this issue (saw few guys above). I will try to play around it more. Cheers!

JlUgia commented 11 years ago

Check Wunderlist. It's insane the amount of elements (built it + custom) we have there, and no issue til now. As @chrisjenx points it has to be something specific from your approach. Still it would be great to find the issue so that we can get to a fix. What you guys have all in common? Can you share your projects in GitHub?

Thanks a lot!

chrisjenx commented 11 years ago

I agree with @JlUgia it must be something specific, but something me and @6wunderkinder aren't doing...

JlUgia commented 11 years ago

Well also the SlidingLayer sample app uses it with a pair of ImageView and Button inside with no issue, although that one is much simpler.

czechooo commented 11 years ago

Just gave it a little bit of testing and found out that following commit brought in changes which are causing problems on my machine:

(Included drawing cache) https://github.com/6wunderkinder/android-sliding-layer-lib/commit/12cbc001e3416f7dfc26ba85b91c7a64782d3085

I tried sample app as well and I get the same error with it. If versions of SlidingLayer from after this commit works for you then it must be a setup I'm using which is pretty much standard:

Android platform 4.2.2 android:minSdkVersion="7" android:targetSdkVersion="17"

I literally have just the most basic project ever with the basic layout: https://gist.github.com/czechooo/5857771

and activity which copies getPrefs() & initState() methods. https://gist.github.com/czechooo/5857776

I hope this will help you guys with more investigation. For a moment I'm happy with using a version from the before of the commit I mentioned earlier.

czechooo commented 11 years ago

I can confirm that after taking the newest version and changing SlidingLayer.setDrawingCacheEnabled(boolean) method to:

public void setDrawingCacheEnabled(boolean enabled) {
        super.setDrawingCacheEnabled(false);
}

my simple project started working. Not the best idea ever to avoid using a cache but it's the only solution for me for the moment it seems.

Hope my little bit of testing will be helpful here. Cheers!

JlUgia commented 11 years ago

What happens if you switch back the cache value to where it was and set the minSdkVers to 8?

czechooo commented 11 years ago

Getting original exception:

java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@40fcf068
JlUgia commented 11 years ago

Good to know. Emulator? Any concrete device?

czechooo commented 11 years ago

Emulator: 4in WVGA (Nexus S)

pr0t3us commented 11 years ago

Happens on Nexus 7 - SlideMenu with ExpandableListView inside.

public void setDrawingCacheEnabled(boolean enabled) {
        super.setDrawingCacheEnabled(false);
}

helps to resolve the problem.

Zordid commented 10 years ago

This IS a bug in the drawing cache implementation of this lib! Guys, could you please fix this??? The key element is the hardware acceleration. If it is enabled, it seems to work, if it is NOT (like on virtual devices!) you will 100% get this exception. Even with the demo app for the sliding lib. It's not people putting complicated things in the layout, it IS this library!

Anybody still working on the lib??

Zordid commented 10 years ago

Gee, I ended up DISABLING the drawing cache when hardware acceleration is not detected. It works. But then, if you read the docs for setDrawingCacheEnabled, you find:

"When hardware acceleration is turned on, enabling the drawing cache has no effect on rendering because the system uses a different mechanism for acceleration which ignores the flag. "

So, in effect: the solution above is the only solution we currently have. But, then: WHY was this drawing cache method implemented in this lib?? Developers, are you listening?

JlUgia commented 10 years ago

Hey Zordid, we are definitely aware of everything you write. Thanks for your time spent on research as all your findings are pretty helpful. We have played a lot with drawing cache since on the one hand we wanted it to be as smooth as possible but also support as many old devices as possible. It has clearly been a source of trouble especially when the hardware acceleration was enforced. Actually I think we did deactivate drawing cache for Wunderlist. I also recall watching a similar problem on SlidingMenu and from what I know there's no drawing cache any more.

Said that, and reason why there are unanswered comments is due to a big lack of spare time to dedicate. Nonetheless that was one of the reasons why it was open sourced for everybody who wanted to contribute. Endorsing @chrisjenx words, we would love to see your findings reflected on a PR to be merged to the lib. In the end that is the goal of it, isn't it?

Don't think about the creators of any open sourced lib as the owners or authors of it since that's precisely what open source is not about. We are really looking forward to your contributions, and ultimately if you neither get the time to address it ;) we'll end up spending the time to do so for you.

Happy coding, and thanks once again for your care and research.

Zordid commented 10 years ago

Thanks for the feedback, Jose! :+1: I just wondered whether the lib was still maintained. You are absolutely right that open source is meant to be developed by more than just the original authors, but I am not the real expert in the Android graphics pipeline. :-) It is extremely weird cause the bug really happens after completed scroll, the drawing cache is disabled again. The complete stacktrace is system internal, Android tries to update all the views and stumbles upon its own "enhancements", aka the Bitmap that is already recycled. I don't really see why... Plus: as the docs mention if hardware acceleration is on, the caching is ignored completely - thus: to be save, the "fix" above which just disables the optimization is the only workaround. And because of this weird behavior I was curious to know what the original authors of this tuning have found when they developed it. Maybe this changed from Android version to version?

When you say that you disabled this in Wunderlist as well, do you mean that you applied the fix by just setting false as shown above?

JlUgia commented 10 years ago

Hey Zordid!

Be sure of it, we are always scratching some minutes every week to keep this up. This problem is a famous one, especially for those who work a lot with bitmaps and views. I'm almost sure the drawing cache approach varies across versions, but most importantly default behavior of hardware acceleration is different in different versions, which makes the outcome it a bit unpredictable. As you pointed, one workaround would be to disable the drawing cache. Although what I'd love to see is a way to just do that in the necessary cases, so by checking hardware acceleration first. The ideal case would be to do some tests around that idea to see if it's applicable or not, having always the disabling of the cache as an ultimate solution.

To be specific, what we do on Wunderlist right now is enable drawing cache when the layer is moving -still we wanted to take advantage of it in the most critical case - and disable it for the rest of cases.

Sagaris commented 10 years ago

Device: Android 4.2.2 on Samsung Galaxy Tab 3 When hardware acceleration is turned off, the Bitmap recycle exception occurs. I need hardware acceleration turned off because of issues with a certain PDF framework (Qoppa). Now the easy temporary fix is to enable hardware acceleration in the manifest and set the "layerType" to "software" (in XML or Java code) on the individual views where hardware acceleration is an issue. So need to mess with cache settings.

nikunjparadva commented 5 years ago

solved it @JlUgia
by adding android:hardwareAccelerated="true"

Thanks man

JlUgia commented 5 years ago

This one since it does not seem actionable anymore. Good to be closed @aconsuegra .