{"action":"created","issue":{"url":"https://api.github.com/repos/bumptech/glide/issues/1179","repository_url":"https://api.github.com/repos/bumptech/glide","labels_url":"https://api.github.com/repos/bumptech/glide/issues/1179/labels{/name}","comments_url":"https://api.github.com/repos/bumptech/glide/issues/1179/comments","events_url":"https://api.github.com/repos/bumptech/glide/issues/1179/events","html_url":"https://github.com/bumptech/glide/issues/1179","id":152804832,"number":1179,"title":"Cant find a way around \"Canvas: trying to use a recycled bitmap\"","user":{"login":"chainani","id":2604487,"avatar_url":"https://avatars.githubusercontent.com/u/2604487?v=3","gravatar_id":"","url":"https://api.github.com/users/chainani","html_url":"https://github.com/chainani","followers_url":"https://api.github.com/users/chainani/followers","following_url":"https://api.github.com/users/chainani/following{/other_user}","gists_url":"https://api.github.com/users/chainani/gists{/gist_id}","starred_url":"https://api.github.com/users/chainani/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chainani/subscriptions","organizations_url":"https://api.github.com/users/chainani/orgs","repos_url":"https://api.github.com/users/chainani/repos","events_url":"https://api.github.com/users/chainani/events{/privacy}","received_events_url":"https://api.github.com/users/chainani/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-05-03T15:35:01Z","updated_at":"2016-05-03T16:12:25Z","closed_at":null,"body":"<!--\r\nPlease fill in the below fields with some data to help us best diagnose the issue.\r\nThe more specific you are, the better! You can help a lot by not making us ask these questions.\r\nFeel free to remove any irrelevant parts that you know are not related to the issue.\r\nAny HTML comment like this will be stripped when rendering markdown, no need to delete them.\r\n-->\r\n\r\n\r\n<!-- What version of Glide you're running, for example: 3.7.1 | 3.8.0-SNAPSHOT | 4.0.0-SNAPSHOT\r\nIt's essentially the version number from your build.gradle: `dependencies { compile '...:x.y.z' }` -->\r\n**Glide Version**: 3.7.0\r\n\r\n<!-- Share the details of your issue in prose, detailing actual and expected behavior. It also helps if you give some info **why** you are trying to do something as opposed to **what** is not working. -->\r\n**Issue details / Repro steps / Use case background**: \r\n\r\nI get an error about trying to use a recycled bitmap. Upon reviewing #857 I realised that this is because I call getDrawable() in a custom image view. I use this to make it so that the image is top crop and  not center crop. Is there any way to work around this?\r\n\r\nAs per @TWiStErRob s suggestion I am reporting a new ticket.\r\n\r\nHere's my code for the ImageView :\r\n```java\r\npublic class TopCropImageView extends ImageView {\r\n\r\n    public TopCropImageView(Context context) {\r\n        super(context);\r\n        setup();\r\n    }\r\n\r\n    public TopCropImageView(Context context, AttributeSet attrs) {\r\n        super(context, attrs);\r\n        setup();\r\n    }\r\n\r\n    public TopCropImageView(Context context, AttributeSet attrs, int defStyle) {\r\n        super(context, attrs, defStyle);\r\n        setup();\r\n    }\r\n\r\n    private void setup() {\r\n        setScaleType(ScaleType.MATRIX);\r\n    }\r\n\r\n    @Override\r\n    protected boolean setFrame(int frameLeft, int frameTop, int frameRight, int frameBottom) {\r\n        recomputeImgMatrix(frameLeft, frameTop, frameRight, frameBottom);\r\n        return super.setFrame(frameLeft, frameTop, frameRight, frameBottom);\r\n    }\r\n\r\n\r\n    private void recomputeImgMatrix(int frameLeft, int frameTop, int frameRight, int frameBottom) {\r\n        if (getDrawable() != null && getScaleType() == ScaleType.MATRIX) {\r\n            float frameWidth = frameRight - frameLeft;\r\n            float frameHeight = frameBottom - frameTop;\r\n\r\n            float originalImageWidth = (float) getDrawable().getIntrinsicWidth();\r\n            float originalImageHeight = (float) getDrawable().getIntrinsicHeight();\r\n\r\n            float usedScaleFactor;\r\n\r\n\r\n                float fitHorizontallyScaleFactor = frameWidth / originalImageWidth;\r\n                float fitVerticallyScaleFactor = frameHeight / originalImageHeight;\r\n\r\n                usedScaleFactor = Math.max(fitHorizontallyScaleFactor, fitVerticallyScaleFactor);\r\n\r\n            Matrix matrix = getImageMatrix();\r\n            matrix.setScale(usedScaleFactor, usedScaleFactor, 0, 0); \r\n            if(fitVerticallyScaleFactor>fitHorizontallyScaleFactor){\r\n                matrix.postTranslate(-((originalImageWidth*usedScaleFactor)-frameWidth)/2,0);\r\n            }\r\n            setImageMatrix(matrix);\r\n        }\r\n    }\r\n}\r\n```\r\n\r\n<!-- How do you use Glide?\r\nMake sure you include everything as is in your app's code:\r\nChanging a single method parameter can yield totally different results.\r\nPlease clarify any magic variables that appear in the code, for example: \"// `this` is a Fragment\"\r\n-->\r\n**Glide load line / `GlideModule` (if any) / list Adapter code (if any)**:\r\n```java\r\nGlide.with(fragment)\r\n.load(imgUrl)\r\n.dontAnimate()\r\n.placeholder(new ColorDrawable(placeholderColor))\r\n.diskCacheStrategy(DiskCacheStrategy.SOURCE)\r\n.into(dest);\r\n```\r\n\r\n<!-- How does your app look like?\r\nWe're most interested in the layout attributes and the hierarchy around the ImageView -->\r\n\r\n\r\n<!--\r\nWhat is the error message that you got in the log?\r\nYou can find some help on diagnosing issues here: https://github.com/bumptech/glide/wiki/Debugging-and-Error-Handling\r\n-->\r\n**Stack trace / LogCat**:\r\n```ruby\r\nFatal Exception: java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@d13d5c7\r\n       at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1270)\r\n       at android.graphics.Canvas.drawBitmap(Canvas.java:1404)\r\n       at com.bumptech.glide.load.resource.bitmap.GlideBitmapDrawable.draw(GlideBitmapDrawable.java:101)\r\n       at android.widget.ImageView.onDraw(ImageView.java:1257)\r\n       at android.view.View.draw(View.java:16194)\r\n       at android.view.View.updateDisplayListIfDirty(View.java:15190)\r\n       at android.view.View.draw(View.java:15964)\r\n       at android.view.ViewGroup.drawChild(ViewGroup.java:3612)\r\n       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)\r\n       at android.view.View.updateDisplayListIfDirty(View.java:15185)\r\n       at android.view.View.draw(View.java:15964)\r\n       at android.view.ViewGroup.drawChild(ViewGroup.java:3612)\r\n       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)\r\n       at android.view.View.draw(View.java:16197)\r\n       at android.view.View.updateDisplayListIfDirty(View.java:15190)\r\n       at android.view.View.draw(View.java:15964)\r\n       at android.view.ViewGroup.drawChild(ViewGroup.java:3612)\r\n       at android.support.v7.widget.RecyclerView.drawChild(RecyclerView.java:3588)\r\n       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)\r\n       at android.view.View.updateDisplayListIfDirty(View.java:15185)\r\n       at android.view.View.draw(View.java:15964)\r\n       at android.view.ViewGroup.drawChild(ViewGroup.java:3612)\r\n       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)\r\n       at android.view.View.draw(View.java:16197)\r\n       at android.view.View.updateDisplayListIfDirty(View.java:15190)\r\n       at android.view.View.draw(View.java:15964)\r\n       at android.view.ViewGroup.drawChild(ViewGroup.java:3612)\r\n       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)\r\n       at android.view.View.updateDisplayListIfDirty(View.java:15185)\r\n       at android.view.View.draw(View.java:15964)\r\n       at android.view.ViewGroup.drawChild(ViewGroup.java:3612)\r\n       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)\r\n       at android.view.View.draw(View.java:16197)\r\n       at android.view.View.updateDisplayListIfDirty(View.java:15190)\r\n       at android.view.View.draw(View.java:15964)\r\n       at android.view.ViewGroup.drawChild(ViewGroup.java:3612)\r\n       at android.support.v4.widget.DrawerLayout.drawChild(DrawerLayout.java:1229)\r\n       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)\r\n       at android.view.View.updateDisplayListIfDirty(View.java:15185)\r\n       at android.view.View.draw(View.java:15964)\r\n       at android.view.ViewGroup.drawChild(ViewGroup.java:3612)\r\n       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)\r\n       at android.view.View.updateDisplayListIfDirty(View.java:15185)\r\n       at android.view.View.draw(View.java:15964)\r\n       at android.view.ViewGroup.drawChild(ViewGroup.java:3612)\r\n       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)\r\n       at android.view.View.updateDisplayListIfDirty(View.java:15185)\r\n       at android.view.View.draw(View.java:15964)\r\n       at android.view.ViewGroup.drawChild(ViewGroup.java:3612)\r\n       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)\r\n       at android.view.View.updateDisplayListIfDirty(View.java:15185)\r\n       at android.view.View.draw(View.java:15964)\r\n       at android.view.ViewGroup.drawChild(ViewGroup.java:3612)\r\n       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3402)\r\n       at android.view.View.draw(View.java:16197)\r\n       at com.android.internal.policy.PhoneWindow$DecorView.draw(PhoneWindow.java:2690)\r\n       at android.view.View.updateDisplayListIfDirty(View.java:15190)\r\n       at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:281)\r\n       at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:287)\r\n       at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:322)\r\n       at android.view.ViewRootImpl.draw(ViewRootImpl.java:2627)\r\n       at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2446)\r\n       at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2079)\r\n       at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1119)\r\n       at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6060)\r\n       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)\r\n       at android.view.Choreographer.doCallbacks(Choreographer.java:670)\r\n       at android.view.Choreographer.doFrame(Choreographer.java:606)\r\n       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)\r\n       at android.os.Handler.handleCallback(Handler.java:746)\r\n       at android.os.Handler.dispatchMessage(Handler.java:95)\r\n       at android.os.Looper.loop(Looper.java:148)\r\n       at android.app.ActivityThread.main(ActivityThread.java:5443)\r\n       at java.lang.reflect.Method.invoke(Method.java)\r\n       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)\r\n       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)\r\n```\r\n\r\n<!-- Bonus points if you attach a relevant screenshot, screen recording or a small demo project -->"},"comment":{"url":"https://api.github.com/repos/bumptech/glide/issues/comments/216580163","html_url":"https://github.com/bumptech/glide/issues/1179#issuecomment-216580163","issue_url":"https://api.github.com/repos/bumptech/glide/issues/1179","id":216580163,"user":{"login":"TWiStErRob","id":2906988,"avatar_url":"https://avatars.githubusercontent.com/u/2906988?v=3","gravatar_id":"","url":"https://api.github.com/users/TWiStErRob","html_url":"https://github.com/TWiStErRob","followers_url":"https://api.github.com/users/TWiStErRob/followers","following_url":"https://api.github.com/users/TWiStErRob/following{/other_user}","gists_url":"https://api.github.com/users/TWiStErRob/gists{/gist_id}","starred_url":"https://api.github.com/users/TWiStErRob/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TWiStErRob/subscriptions","organizations_url":"https://api.github.com/users/TWiStErRob/orgs","repos_url":"https://api.github.com/users/TWiStErRob/repos","events_url":"https://api.github.com/users/TWiStErRob/events{/privacy}","received_events_url":"https://api.github.com/users/TWiStErRob/received_events","type":"User","site_admin":false},"created_at":"2016-05-03T16:12:25Z","updated_at":"2016-05-03T16:12:25Z","body":"I think this may not be related to the code in `TopCropImageView`. That kind of `getDrawable()` access is safe, because the `ImageView` still owns the Drawable, you're just querying the size of it on the UI thread. Any lifecycle will also happen on the UI thread so there's no threading issue either.\r\nYou can easily confirm that the exception is coming from `TopCropImageView`: override `onDraw()` and just call super; this will make `TopCropImageView` appear in the stack trace.\r\n\r\nWhat is `dest` in your Glide load line?\r\n\r\n---\r\nOther notes, unrelated to the issue: I think you're working around Glide a lot here. I think the optimal way for this would be to create a custom transformation that does something similar to `CenterCrop`, but the alignment is to the top (probably `dy = 0` in `TransformationUtils.centerCrop`). To use this you would do: `.transform(new TopCrop(context)).into(dest)` and `scaleType` could be anything and there's no need to have a custom ImageView. This transformation could be cached as well in RESULT cache."}}