System.ObjectDisposedException: Cannot access a disposed object when using ScrollView

samgaksamgak NZMember ✭✭
edited May 2017 in Xamarin.Forms

I have a Xamarin.Forms app that includes a ContentPage with a ScrollView, where the ScrollView is initially hidden, but in response to a UI event I show it by setting IsVisible to true and calling ScrollToAsync on the ScrollView. After recently upgrading Xamarin.Forms, this causes this exception:

Xamarin caused by: android.runtime.JavaProxyThrowable: System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'Xamarin.Forms.Platform.Android.ScrollViewRenderer'.
Java.Interop.JniPeerMembers.AssertSelf(IJavaPeerable self)<3a653d21f22f4786bf9d5acf69f4a22e>:0
Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualBooleanMethod(string encodedMember, IJavaPeerable self, JniArgumentValue* parameters)<3a653d21f22f4786bf9d5acf69f4a22e>:0
Android.Views.View.get_IsLayoutRequested()<cba5498252974515814d3da6e57d094c>:0
Xamarin.Forms.Platform.Android.ScrollViewRenderer.<OnScrollToRequested>d__44.MoveNext()<15c9790557774c809371f43133cc42c4>:0
Android.App.SyncContext.<>c__DisplayClass2_0.<Post>b__0()<cba5498252974515814d3da6e57d094c>:0
Java.Lang.Thread.RunnableImplementor.Run()<cba5498252974515814d3da6e57d094c>:0
Java.Lang.IRunnableInvoker.n_Run(IntPtr jnienv, IntPtr native__this)<cba5498252974515814d3da6e57d094c>:0
at (wrapper dynamic-method) System.Object:ba3ec2cc-2626-44c0-ab76-80f16217bdbf (intptr,intptr)
mono.java.lang.RunnableImplementor.n_run(Native Method)
mono.java.lang.RunnableImplementor.run()RunnableImplementor.java:30
android.os.Handler.handleCallback()Handler.java:739
android.os.Handler.dispatchMessage()Handler.java:95
android.os.Looper.loop()Looper.java:158
android.app.ActivityThread.main()ActivityThread.java:7229
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run()ZygoteInit.java:1230
com.android.internal.os.ZygoteInit.main()ZygoteInit.java:1120

I managed to find a workaround, which is to call ScrollToAsync like this:

public async Task DelayActionAsync(int delay, Action action) 
{
    await Task.Delay(delay);

    action();
}

and replace my ScrollToAsync call with this:

 DelayActionAsync(100, () => {myScrollView.ScrollToAsync(positionX, positionY, false);} );

and this gets rid of the crash (sorry for any errors, this is typed from memory).

My question is, why do I have to do this? Is this just a bug in Xamarin.Forms that I am working around, or is this the recommended and correct way, and I was just lucky it wasn't crashing previously? If the latter, can anyone point me to any documentation about why this is so?

The crash only occurred on certain Android devices, and only in release builds. That doesn't mean it's a Xamarin bug of course because it could be a timing bug in my code that only gets triggered on certain devices. I just want to know how to code defensively to avoid these errors.

Answers

Sign In or Register to comment.