Closed MaskPZ closed 4 years ago
"Cannot access a disposed object. Object name: 'Refractored.XamForms.PullToRefresh.Droid.PullToRefreshLayoutRenderer'."
When I use camera from Xam.Plugin.Media. I got same exception.
forms version is 2.3.1.114.
I got the same problem on a specific page in my application. First time opening it is not problem, but the second time it crashes with the error. My Xamarin.Forms version is 2.3.0.107. I can also confirm it's Android only. If it helps, in my case it's a page that is added as a child of a tabbed page. But the weird thing is I don't use the pulltorefresh functionality on that page.
I did some debugging today, it seems that it has to do with using the PullToRefreshLayout
in a ContentView
. It was not working very well from a user perspective anyway, so I just moved it to my parent (ContentPage
) page where I already included this ContentView
. I no longer get this crash now, so it seems to be resolved. I don't know if the others that posted here have or had the same situation?
Hi!
Since I updated Xamarin Forms to v2.3.2.127 i'm getting this exception while using PullToRefreshlayout. I'm using the pull to refresh in a Content Page. To reproduce the problem I have to open the View once, close the View, open the View again and rotate the device to landscape mode. If i rotate the device in the first time I open the View, the app don´t crash.
@DotControlNB My PullToRefresh is nested in a ContentPage and still the app crashes..
It seems to happen when navigating to a TabbedPage before navigating to a page containing PullToRefreshLayout.
Edit: Happens only on Holo theme, works on Material
Still with this problem :s the component is so good but after uptading xamarin forms it started to have this problem. Since no one atached the exception here it is:
Fatal Exception: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
Caused by java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
Caused by android.runtime.JavaProxyThrowable: System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'Refractored.XamForms.PullToRefresh.Droid.PullToRefreshLayoutRenderer'.
at Java.Interop.JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self) [0x00030] in 1[T] e) [0x00049] in <95895bcb439e42ebb8e7134a545f1acc>:0 at (wrapper delegate-invoke) System.EventHandler
1[Xamarin.Forms.EventArg1[Xamarin.Forms.VisualElement]]:invoke_void_object_TEventArgs (object,Xamarin.Forms.EventArg
1
We are still getting this Cannot access a disposed object exception, the control is very good, but we can't find the solution to this bug...
We tried to override the dispose method, move things around... but nothing helps. I don't know if this is an issue with the control or if it is a Xamarin bug.
I don't know if it's only me, but with Android I still have the same issue. Xamarin version 2.3.2.127. In your fix I can see only some code about iOS (PullToRefresh/PullToRefresh.iOS/PullToRefreshLayoutRenderer.cs) but nothing about Android. So the issue is still there.
Thanks
confirming the same error under droid
Does anyone have a small repo they can attach
I need sample code that I can run and reproduce please.
Hi James I don't think you have anything to fix in this project. It looks like the bug is in Xamarin Forms and not fixed yet. https://bugzilla.xamarin.com/show_bug.cgi?id=42678 Regards :-)
Hi @jamesmontemagno,
You need to properly implement the Dispose
method to fix this problem. Probably, it would be enough to do Element.PropertyChanged -= HandlePropertyChanged
. But please check how other renderers in Xamarin.Android are implemented, and what they do in Dispose
.
pushing a new beta out to try out.
Here's a sample app that reproduces the issue for me: https://github.com/22222/XamarinFormsTestApp. I still get the exception with those new changes to the renderer's Dispose
method.
At least for the way I've run into the issue, the key steps seem to be:
PullToRefreshLayout
as the Content
of a ContentPage
PullToRefreshLayout
with some other viewPullToRefreshLayout
back as the ContentWhen you remove the PullToRefreshLayout
as the Content
(step 2), the Android PullToRefreshLayoutRenderer
's Dispose
method is called. Then when you set it back as the content (step 3), you get that exception because the Android SwipeRefreshLayout
is disposed.
If you use a ScrollView
or ListView
instead of a PullToRefreshLayout
, then the above steps work fine and you don't get the ObjectDisposedException
. So there must be something that those renderers are doing differently?
Hi I'm using 1.2.0.4-beta version with Xamarin.Forms v2.3.3.180 and still gets the error. Which is the maximum version of Xamarin.Forms I have to use to avoid that issue?
@22222 the issue here from your code is that when you replace the "Content" with the activity indicator then Xamarin.Forms disposes of your UI, but then you are setting it back so it is already disposed. Since I am disposing of everything properly that is why. This may be a change in how XF worked though.
It apparently only happens when not in a navigation page from my testing.
I have adjusted how it works with my dispose so the next beta shoudl work there.
I have now fixed this for Android. If there is still an issue with iOS please let me know and open a NEW issue with a proper sample repo that I can test.
I've updated to the latest beta 1.2.0.5-beta
and am still seeing this crash.
Occurs when the device is rotated after clicking through a few tabs. Droid only. Anyone figure out a work around here?
Stack trace below:
Same here, don't have to rotate, just flip through a few pages. Then the app crashes with the above error message. Please reopen this thread again.
If someone wants to put a use case in the sample app I can try to diagnose.
I get this error on tabbedpage everytime i'm trying to rotate with atleast 1 tab inbetween the page i'm rotating on and a page that contains PullToRefresh, i'm trying on android with forms 2.3.4.221-pre6 and PullToRefresh 1.2.0.5b.
To clarify, if i have a tabbedpage with 3 tabs and put PullToRefresh in tab 1 and rotate on tab3 it will crash(works on tab2), if i would instead put PullToRefresh in tab 2 then it will work fine to rotate on both tab1 and tab2.
It also crashes if i use TakePhotoAsync() with your plugin.media instead of rotating so i assume it's everytime the page have to refresh/rebuild the ui.
I have the same crash. Have no idea yet how to workaround it.
Is this fixed?
Hi, is there a wordaround. I have the same issue. I can't reproduce it very clearly, and I can't trace back to the issue. Is there a way to avoid it?
I have a new 2.0.0-beta that i just pushed, that may work better in some instances. It seems like a lot of issues are when you cache a page or view around for use later.
I am working with the forms team later this week to see if something weird is going on.
If helpful - shorter stack trace of the same issue. I'm seeing this occasionally but very rarely happening with XF 2.3.4.247, didn't try out the beta yet.
Xamarin caused by: android.runtime.JavaProxyThrowable: System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'Refractored.XamForms.PullToRefresh.Droid.PullToRefreshLayoutRenderer'.
Java.Interop.JniPeerMembers.AssertSelf(IJavaPeerable self)<efcdcdca54d241a682e3c423f0aa3fc6>:0
Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualBooleanMethod(string encodedMember, IJavaPeerable self, JniArgumentValue* parameters)<efcdcdca54d241a682e3c423f0aa3fc6>:0
Android.Views.View.get_IsInLayout()<6d5b488990324d4ca6d28e34a1cffa58>:0
Xamarin.Forms.Platform.Android.VisualElementTracker.MaybeRequestLayout()<1481f85a917c4f2b882ea161e9bc082f>:0
Xamarin.Forms.Platform.Android.VisualElementTracker.HandleRedrawNeeded(object sender, EventArg<T> e)<1481f85a917c4f2b882ea161e9bc082f>:0
System.EventHandler<EventArg<VisualElement>>.invoke_void_object_TEventArgs(object, EventArg<VisualElement>)(wrapper delegate-invoke)
Xamarin.Forms.VisualElement.BatchCommit()<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.VisualElement.set_Bounds(Rectangle value)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.VisualElement.Layout(Rectangle bounds)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.Layout.LayoutChildIntoBoundingRegion(VisualElement child, Rectangle region)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.ContentPresenter.LayoutChildren(double x, double y, double width, double height)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.Layout.UpdateChildrenLayout()<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.Layout.OnSizeAllocated(double width, double height)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.VisualElement.SizeAllocated(double width, double height)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.VisualElement.SetSize(double width, double height)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.VisualElement.set_Bounds(Rectangle value)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.VisualElement.Layout(Rectangle bounds)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.Layout.LayoutChildIntoBoundingRegion(VisualElement child, Rectangle region)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.Grid.LayoutChildren(double x, double y, double width, double height)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.Layout.UpdateChildrenLayout()<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.Layout.OnSizeAllocated(double width, double height)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.VisualElement.SizeAllocated(double width, double height)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.VisualElement.SetSize(double width, double height)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.VisualElement.set_Bounds(Rectangle value)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.VisualElement.Layout(Rectangle bounds)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.Layout.LayoutChildIntoBoundingRegion(VisualElement child, Rectangle region)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.TemplatedView.LayoutChildren(double x, double y, double width, double height)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.Layout.UpdateChildrenLayout()<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.Layout.OnSizeAllocated(double width, double height)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.VisualElement.SizeAllocated(double width, double height)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.VisualElement.SetSize(double width, double height)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.VisualElement.set_Bounds(Rectangle value)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.VisualElement.Layout(Rectangle bounds)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.Layout.LayoutChildIntoBoundingRegion(View child, Rectangle region, SizeRequest childSizeRequest)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.StackLayout.LayoutChildren(double x, double y, double width, double height)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.Layout.UpdateChildrenLayout()<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.Layout.OnSizeAllocated(double width, double height)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.VisualElement.SizeAllocated(double width, double height)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.VisualElement.SetSize(double width, double height)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.VisualElement.set_Bounds(Rectangle value)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.VisualElement.Layout(Rectangle bounds)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.Layout.LayoutChildIntoBoundingRegion(VisualElement child, Rectangle region)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.TemplatedView.LayoutChildren(double x, double y, double width, double height)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.Layout.UpdateChildrenLayout()<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.Layout.OnIsVisibleChanged(bool oldValue, bool newValue)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
at Xamarin.Forms.VisualElement+<>c.<.cctor>b__212_2 (Xamarin.Forms.BindableObject bindable, System.Object oldvalue, System.Object newvalue) [0x00000] in <0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.BindableObject.SetValueActual(BindableProperty property, BindableObject.BindablePropertyContext context, object value, bool currentlyApplying, BindableObject.SetValueFlags attributes, bool silent)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.BindableObject.SetValueCore(BindableProperty property, object value, BindableObject.SetValueFlags attributes, BindableObject.SetValuePrivateFlags privateAttributes)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.BindableObject.SetValue(BindableProperty property, object value, bool fromStyle, bool checkAccess)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.BindableObject.SetValue(BindableProperty property, object value)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.VisualElement.set_IsVisible(bool value)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Ridr.Client.Controls.Tabs.OnTabSwitch(int index)<e011caed1f184b02a01254685e487e1d>:0
Ridr.Client.Controls.Tabs.OnSelectedIndexChanged(BindableObject bindable, object oldValue, object newValue)<e011caed1f184b02a01254685e487e1d>:0
Xamarin.Forms.BindableObject.SetValueActual(BindableProperty property, BindableObject.BindablePropertyContext context, object value, bool currentlyApplying, BindableObject.SetValueFlags attributes, bool silent)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.BindableObject.SetValueCore(BindableProperty property, object value, BindableObject.SetValueFlags attributes, BindableObject.SetValuePrivateFlags privateAttributes)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.BindingExpression.ApplyCore(object sourceObject, BindableObject target, BindableProperty property, bool fromTarget)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.BindingExpression.Apply(bool fromTarget)<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Xamarin.Forms.BindingExpression.BindingExpressionPart.<PropertyChanged>b__47_0()<0f1ce60dbc6b4e24af01294c7acf41c6>:0
Java.Lang.Thread.RunnableImplementor.Run()<6d5b488990324d4ca6d28e34a1cffa58>:0
Java.Lang.IRunnableInvoker.n_Run(IntPtr jnienv, IntPtr native__this)<6d5b488990324d4ca6d28e34a1cffa58>:0
at (wrapper dynamic-method) System.Object:486506db-450f-4820-b242-5ff9da89432c (intptr,intptr)
mono.java.lang.RunnableImplementor.n_run(Native Method)
mono.java.lang.RunnableImplementor.run()RunnableImplementor.java:30
android.os.Handler.handleCallback()Handler.java:751
android.os.Handler.dispatchMessage()Handler.java:95
android.os.Looper.loop()Looper.java:241
android.app.ActivityThread.main()ActivityThread.java:6274
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run()ZygoteInit.java:886
com.android.internal.os.ZygoteInit.main()ZygoteInit.java:776
Hey @jamesmontemagno,
Any update on this issue?
@jamesmontemagno I think you're going to want to do some eager disposal, like we're doing here now. https://github.com/xamarin/Xamarin.Forms/pull/1063
I'm experiencing the same object disposed exception on XF 2.4.0.
I'm not sure if some behaviour has changed in XF but it looks like the property changed handler in the view renderer isn't being unregistered. There's some commented out code here that looks like it would fix my issue, at least it has for other custom renderers I have.
@FrameV this does not fix your issue and i have no idea how to fix this as it only happens when you use it a weird way. Hence I have never fixed it as I have no idea.
@jamesmontemagno thanks for the reply. I don't think I'm using it in such a weird way but it could be, I'll do some debugging tomorrow and see if I can help.
I took a copy of the library and did some debugging in my solution.
I've found that the PropertyChanged event is never unregistered. I did not see my debugger hit the code at this line at all. Is this a change in XF behaviour?
When I navigate to another page inside my app, dispose is called on the renderer.
When I return to the page and a binding in my app causes the PropertyChanged event to fire, I see the event fire on what is presumably the view on screen, and then the app crashes as I assume it is trying to call the event on the object that has since been disposed.
Adding the commented out code back in fixes the issue for me on XF 2.4.0. It was also important to dispose of the VisualElementTracker too or else it would also cause an object disposed exception.
Xamarin Exception Stack:
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'Refractored.XamForms.PullToRefresh.Droid.PullToRefreshLayoutRenderer'.
at Java.Interop.JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self) [0x00029] in <1d799d87381c4db5b1252825fd105b84>:0
at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualBooleanMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x00000] in <1d799d87381c4db5b1252825fd105b84>:0
at Android.Views.View.get_IsInLayout () [0x0000a] in 1[T] e) [0x00049] in <398cf4d138ad48c7a756f39dfc252737>:0 at (wrapper delegate-invoke) System.EventHandler
1[Xamarin.Forms.Internals.EventArg1[Xamarin.Forms.VisualElement]]:invoke_void_object_TEventArgs (object,Xamarin.Forms.Internals.EventArg
1
@jamesmontemagno I have just experienced this crash also - for me it occurs when navigating pages quickly, before the content within the PullToRefreshLayout has finished rendering. I don't know if that information helps at all?
(Great package btw, just what we needed for our project)
I had this issue as well, but running VIsual Studio and administrator, cleaning then rebuilding the project cured it for me, this was however only an issue on the release version for Android, the debug version always worked ok
Unfortunately we've had to remove PullToRefreshLayout from our project because we are experiencing this crash very often on Droid (iOS seems to be fine). I can reproduce this in two ways:
In both cases you can see from the stacktrace that the exception is occuring within HandlePropertyChanged. So it must be case of needing to unregister from PropertyChanged events on disposal. Was there a reason for commenting out your code that did this? Would it hurt to reinstate it?
I'm also experiencing the same problem. Any workaround for this?
I think I finally managed to workaround this. I included the renderer code in my code base.
Then I overridden all the properties and methods that throw ObjectDisposedException
from the native part: IsInLayout
, IsLayoutRequested
, Visibility
and few others. The overrides simply wrap the base call (or renderer code) in try-catch
block with some logging.
I also added the constructor PullToRefreshLayoutRenderer(IntPtr javaReference, JniHandleOwnership transfer)
(I observed MissingMethodException
error related with that).
Since the error seems to appear on control disappearance it works in my case. Although it's ugly... Here is the link to GIST with code.
PullToRefreshLayoutRenderer(IntPtr javaReference, JniHandleOwnership transfer)
should not be implemented at all, it hides usage of already disposed PullToRefreshLayoutRenderer object
@paleicikas I'm not sure if I understand correctly. Could you describe it in more detail? What are the consequences of implementing it?
As I understand, MissingMethodException
means that PullToRefreshLayoutRenderer already disposed, and there is not need call any methods/properties. Its common problem with all android renderers.
Got it. One error entrails the other. Still I found no other solution for this issue. I hope I will get rid of this workaround as soon as possible.
Just to add to the mix, I get the disposed object issue as well now, but currently only when the screen is being rotated.
this old bug is not fixed yet?? I am facing this crash with Xamarin Forms 3.x. please help to fix, thx
This seems to be highly related to the following Xamarin.Forms bug: https://github.com/xamarin/Xamarin.Forms/issues/2004
I get this bug also. It happens in my app when I switch tabs and then come back to the original tab with the ContentView containing the control. Works fine on iOS. I narrowed it down to data binding the IsPullToRefreshEnabled property. If I remove data binding to that property it works without issue.
this seems to be highly related to the following Xamarin.Forms bug: xamarin/Xamarin.Forms#2004
Just want to mention that this forms issue with accessing to disposed object is fixed in 3.2.0.729530-pre2 , but reported PullToRefresh crash is still happening.
I narrowed it down to data binding the IsPullToRefreshEnabled property. If I remove data binding to that property it works without issue.
For me it does not help(actually I never had this binding) - still crashing on screen rotation.
Actually for me it helped to add dispose for Tracker property in PullToRefreshRender Dispose. So tracker will unregister from event handlers and will not try to access to disposed PullToRefreshRenderer. Thanks old and new gods that Tracker property has public getter. Here:
public class FaultTolerantPullToRefreshRenderer : PullToRefreshLayoutRenderer
{
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
Tracker?.Dispose();
}
}
Hi James,
First of all thank you for your great work! I'm using this control since time and it always worked perfectly!
A few days ago, I've updated to Xamarin.Forms 2.3.1.114 and since then...when I open the page containing the control the first time everything is ok but if I try to re-open it I get this:
"Unhandled Exception: System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'Refractored.XamForms.PullToRefresh.Droid.PullToRefreshLayoutRenderer'."
Same error also after app resume.
As you can see it's on Android, never tried on iOS.
Hope you will fix it.
Thank you