Xamarin.forms: [Android] Object name: 'Android.Graphics.Bitmap' System.ObjectDisposedException: Cannot access a disposed object.

Created on 6 Apr 2018  ·  5Comments  ·  Source: xamarin/Xamarin.Forms

Description

Bugzilla bug https://bugzilla.xamarin.com/show_bug.cgi?id=57789. I didn't submit the original bug, but it has just started happening to me (although with newer versions of Xamarin Forms).

Tapping a button sometimes triggers an ObjectDisposedException in either ButtonDrawable.Draw or ButtonDrawable.Reset. This is on Android AppCompat with fast renderers enabled. The buttons in question trigger navigation.

Steps to Reproduce

Unclear. The only significant change between it not happening and it happening (for me at least) was moving the content with the buttons inside a CarouselViewControl. This is the one by alexrainman, and I'm still referencing his Nuget package.

Sadly, I cannot as yet produce a small reproducible sample, but I will see what I can come up with.

Expected Behavior

No exception.

Actual Behavior

Object name: 'Android.Graphics.Bitmap' System.ObjectDisposedException: Cannot access a disposed object.

Basic Information

  • Version with issue: 2.5.1.392594-pre3 - 2.5.1.444934
  • Platform Target Frameworks:

    • Android: 8.1

  • Android Support Library Version: 26.0.2

Stack trace for ButtonDrawable.Draw case

FATAL EXCEPTION: ControllerMessenger
android.runtime.JavaProxyThrowable: System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'Android.Graphics.Bitmap'.
  at Java.Interop.JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self) [0x00029] in <f866b6cd018644318f402b6eff2ef567>:0 
  at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeNonvirtualInt32Method (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x00000] in <f866b6cd018644318f402b6eff2ef567>:0 
  at Android.Graphics.Bitmap.get_Height () [0x0000a] in <a5a2b49c08aa41daafa07f33a46747ba>:0 
  at Xamarin.Forms.Platform.Android.ButtonDrawable.Draw (Android.Graphics.Canvas canvas) [0x00029] in <fa196d4afd1b4356b38d6cf3bb1e4df8>:0 
  at Android.Graphics.Drawables.Drawable.n_Draw_Landroid_graphics_Canvas_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_canvas) [0x0000f] in <a5a2b49c08aa41daafa07f33a46747ba>:0 
  at (wrapper dynamic-method) System.Object.310e6f61-0a59-4976-8037-aa9560b7943e(intptr,intptr,intptr)
    at md5b60ffeb829f638581ab2bb9b1a7f4f3f.ButtonDrawable.n_draw(Native Method)
    at md5b60ffeb829f638581ab2bb9b1a7f4f3f.ButtonDrawable.draw(ButtonDrawable.java:50)
    at android.graphics.drawable.RippleDrawable.drawContent(RippleDrawable.java:841)
    at android.graphics.drawable.RippleDrawable.draw(RippleDrawable.java:698)
    at android.view.View.getDrawableRenderNode(View.java:19377)
    at android.view.View.drawBackground(View.java:19313)
    at android.view.View.draw(View.java:19110)
    at android.view.View.updateDisplayListIfDirty(View.java:18069)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
    at android.view.View.updateDisplayListIfDirty(View.java:18028)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
    at android.view.View.updateDisplayListIfDirty(View.java:18028)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
    at android.view.View.updateDisplayListIfDirty(View.java:18028)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
    at android.view.View.updateDisplayListIfDirty(View.java:18028)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
    at android.view.View.updateDisplayListIfDirty(View.java:18028)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
    at android.view.View.updateDisplayListIfDirty(View.java:18028)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
    at android.view.View.updateDisplayListIfDirty(View.java:18028)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
    at android.view.View.updateDisplayListIfDirty(View.java:18028)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
    at android.view.View.updateDisplayListIfDirty(View.java:18028)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
    at android.view.View.updateDisplayListIfDirty(View.java:18028)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
    at android.view.View.updateDisplayListIfDirty(View.java:18028)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
    at android.view.View.updateDisplayListIfDirty(View.java:18028)
    at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
    at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
    at android.view.View.updateDisplayListIfDirty(View.java:18028)
    at android.view.View.draw(View.java:18847)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
    at android.view.View.updateDisplayListIfDirty(View.java:18060)
    at android.view.View.draw(View.java:18847)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
    at android.view.View.updateDisplayListIfDirty(View.java:18060)
    at android.view.View.draw(View.java:18847)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
    at android.view.View.updateDisplayListIfDirty(View.java:18060)
    at android.view.View.draw(View.java:18847)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
    at android.view.View.updateDisplayListIfDirty(View.java:18060)
    at android.view.View.draw(View.java:18847)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
    at android.view.View.updateDisplayListIfDirty(View.java:18060)
    at android.view.View.draw(View.java:18847)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
    at android.view.View.updateDisplayListIfDirty(View.java:18060)
    at android.view.View.draw(View.java:18847)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
    at android.view.View.updateDisplayListIfDirty(View.java:18060)
    at android.view.View.draw(View.java:18847)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
    at android.view.View.draw(View.java:19122)
    at com.android.internal.policy.DecorView.draw(DecorView.java:785)
    at android.view.View.updateDisplayListIfDirty(View.java:18069)
    at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:643)
    at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:649)
    at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:757)
    at android.view.ViewRootImpl.draw(ViewRootImpl.java:2980)
    at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2794)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2347)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1386)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6733)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
    at android.view.Choreographer.doCallbacks(Choreographer.java:723)
    at android.view.Choreographer.doFrame(Choreographer.java:658)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
    at android.os.Handler.handleCallback(Handler.java:789)
    at android.os.Handler.dispatchMessage(Handler.java:98)
    at android.support.test.espresso.base.Interrogator.loopAndInterrogate(Interrogator.java:148)
    at android.support.test.espresso.base.UiControllerImpl.loopUntil(UiControllerImpl.java:465)
    at android.support.test.espresso.base.UiControllerImpl.loopUntil(UiControllerImpl.java:421)
    at android.support.test.espresso.base.UiControllerImpl.injectMotionEvent(UiControllerImpl.java:235)
    at android.support.test.espresso.action.MotionEvents.sendUp(MotionEvents.java:140)
    at android.support.test.espresso.action.MotionEvents.sendUp(MotionEvents.java:123)
    at android.support.test.espresso.action.Tap.sendSingleTap(Tap.java:170)
    at android.support.test.espresso.action.Tap.access$100(Tap.java:31)
    at android.support.test.espresso.action.Tap$1.sendTap(Tap.java:47)
    at android.support.test.espresso.action.GeneralClickAction.perform(GeneralClickAction.java:136)
    at android.support.test.espresso.ViewInteraction$SingleExecutionViewAction.perform(ViewInteraction.java:356)
    at android.support.test.espresso.ViewInteraction.doPerform(ViewInteraction.java:248)
    at android.support.test.espresso.ViewInteraction.access$100(ViewInteraction.java:63)
    at android.support.test.espresso.ViewInteraction$1.call(ViewInteraction.java:153)
    at android.support.test.espresso.ViewInteraction$1.call(ViewInteraction.java:150)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at android.os.Handler.handleCallback(Handler.java:789)
    at android.os.Handler.dispatchMessage(Handler.java:98)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6541)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

Stack trace for ButtonDrawable.Reset case

FATAL EXCEPTION: ControllerMessenger
android.runtime.JavaProxyThrowable: System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'Android.Graphics.Bitmap'.
  at Java.Interop.JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self) [0x00029] in <f866b6cd018644318f402b6eff2ef567>:0 
  at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeAbstractVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x00000] in <f866b6cd018644318f402b6eff2ef567>:0 
  at Android.Graphics.Bitmap.Recycle () [0x0000a] in <a5a2b49c08aa41daafa07f33a46747ba>:0 
  at Xamarin.Forms.Platform.Android.ButtonDrawable.Reset () [0x00008] in <fa196d4afd1b4356b38d6cf3bb1e4df8>:0 
  at Xamarin.Forms.Platform.Android.ButtonDrawable.Dispose (System.Boolean disposing) [0x00013] in <fa196d4afd1b4356b38d6cf3bb1e4df8>:0 
  at Java.Lang.Object.Dispose () [0x00000] in <a5a2b49c08aa41daafa07f33a46747ba>:0 
  at Xamarin.Forms.Platform.Android.ButtonBackgroundTracker.Dispose (System.Boolean disposing) [0x00015] in <fa196d4afd1b4356b38d6cf3bb1e4df8>:0 
  at Xamarin.Forms.Platform.Android.ButtonBackgroundTracker.Dispose () [0x00000] in <fa196d4afd1b4356b38d6cf3bb1e4df8>:0 
  at Xamarin.Forms.Platform.Android.FastRenderers.ButtonRenderer.Dispose (System.Boolean disposing) [0x00057] in <fa196d4afd1b4356b38d6cf3bb1e4df8>:0 
  at Java.Lang.Object.Dispose () [0x00000] in <a5a2b49c08aa41daafa07f33a46747ba>:0 
  at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].Dispose (System.Boolean disposing) [0x0007b] in <fa196d4afd1b4356b38d6cf3bb1e4df8>:0 
  at Java.Lang.Object.Dispose () [0x00000] in <a5a2b49c08aa41daafa07f33a46747ba>:0 
  at Xamarin.Forms.Platform.Android.FastRenderers.FrameRenderer.Dispose (System.Boolean disposing) [0x0006d] in <fa196d4afd1b4356b38d6cf3bb1e4df8>:0 
  at Java.Lang.Object.Dispose () [0x00000] in <a5a2b49c08aa41daafa07f33a46747ba>:0 
  at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].Dispose (System.Boolean disposing) [0x0007b] in <fa196d4afd1b4356b38d6cf3bb1e4df8>:0 
  at Java.Lang.Object.Dispose () [0x00000] in <a5a2b49c08aa41daafa07f33a46747ba>:0 
  at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].Dispose (System.Boolean disposing) [0x0007b] in <fa196d4afd1b4356b38d6cf3bb1e4df8>:0 
  at Java.Lang.Object.Dispose () [0x00000] in <a5a2b49c08aa41daafa07f33a46747ba>:0 
  at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].Dispose (System.Boolean disposing) [0x0007b] in <fa196d4afd1b4356b38d6cf3bb1e4df8>:0 
  at Xamarin.Forms.Platform.Android.PageRenderer.Dispose (System.Boolean disposing) [0x00011] in <fa196d4afd1b4356b38d6cf3bb1e4df8>:0 
  at Java.Lang.Object.Dispose () [0x00000] in <a5a2b49c08aa41daafa07f33a46747ba>:0 
  at Xamarin.Forms.Platform.Android.AppCompat.FragmentContainer.OnDestroyView () [0x0003c] in <fa196d4afd1b4356b38d6cf3bb1e4df8>:0 
  at Android.Support.V4.App.Fragment.n_OnDestroyView (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in <575255b84b4942aa8ea338ee45ed50f6>:0 
  at (wrapper dynamic-method) System.Object.5b9d693b-68e1-4728-806f-455ac3923dce(intptr,intptr)
    at md5270abb39e60627f0f200893b490a1ade.FragmentContainer.n_onDestroyView(Native Method)
    at md5270abb39e60627f0f200893b490a1ade.FragmentContainer.onDestroyView(FragmentContainer.java:41)
    at android.support.v4.app.Fragment.performDestroyView(Fragment.java:2575)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1503)
    at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1740)
    at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:794)
    at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2580)
    at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2367)
    at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2322)
    at andr
Android needs-repro ❔ bug

Most helpful comment

@bastianbecker21 I can tell you what I have found so far.

I am experiencing the same error and so far have tracked it down to a binding I have on the button's IsEnabled property. This binding is being updated after the page has been navigated away from and the Root page has been swapped out.

I have to do more testing to be 100% sure this is the cause, but thought it may help.

All 5 comments

Unfortunately without even a reproduction using the nuget it will be pretty hard to work this out. This appears to be something unfriendly happening with fragments and that carouselview causing disposed objects to be requested back to life.

While trying to create a simple reproduction, I decided to try updating the version of the carousel package (from 4.4.6 to 5.2). The problem seemed to go away so I'm happy to accept this as a old bug in the carousel.

I realise that this doesn't really make the bug any more actionable, but I figured I might as well gather the information in one place in case it becomes useful to someone.

I just got the Reset version of the exception again (via crash reporting, not something I've seen myself). It wasn't on a page with a carousel (and this is after updating the carousel).

I think the Draw case I originally reported may have been caused by the carousel bringing the object back to life. I don't think the Reset case is.

@GalaxiaGuy I am getting same crash report but I can't guess what is the issue, please help me to fix it if you can. Thanks. Here is the error what I got from app center.

[JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self)
System.ObjectDisposedException: Cannot access a disposed object. Object name: 'Android.Graphics.Bitmap'.
JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self)
JniPeerMembers+JniInstanceMethods.InvokeAbstractVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters)
Bitmap.Recycle ()
ButtonDrawable.Reset ()
ButtonDrawable.Dispose (System.Boolean disposing)
Object.Dispose ()
ButtonBackgroundTracker.Dispose (System.Boolean disposing)
ButtonBackgroundTracker.Dispose ()
ButtonRenderer.Dispose (System.Boolean disposing)
Object.Dispose ()
VisualElementRenderer`1[TElement].Dispose (System.Boolean disposing)
Object.Dispose ()
VisualElementRenderer`1[TElement].Dispose (System.Boolean disposing)
Object.Dispose ()
VisualElementRenderer`1[TElement].Dispose (System.Boolean disposing)
Object.Dispose ()
VisualElementRenderer`1[TElement].Dispose (System.Boolean disposing)
Object.Dispose ()
VisualElementRenderer`1[TElement].Dispose (System.Boolean disposing)
Object.Dispose ()
VisualElementRenderer`1[TElement].Dispose (System.Boolean disposing)
Object.Dispose ()
VisualElementRenderer`1[TElement].Dispose (System.Boolean disposing)
PageRenderer.Dispose (System.Boolean disposing)
Object.Dispose ()
FragmentContainer.OnDestroyView ()
Fragment.n_OnDestroyView (System.IntPtr jnienv, System.IntPtr native__this)
(wrapper dynamic-method) System.Object.b90f1b0c-e5ee-4b98-a069-dc4d6ef30055(intptr,intptr)](url)

@bastianbecker21 I can tell you what I have found so far.

I am experiencing the same error and so far have tracked it down to a binding I have on the button's IsEnabled property. This binding is being updated after the page has been navigated away from and the Root page has been swapped out.

I have to do more testing to be 100% sure this is the cause, but thought it may help.

Was this page helpful?
0 / 5 - 0 ratings