Skip to content

Cannot access a disposed object: Android.Webkit.WebView #6

@casas333

Description

@casas333

Steps to reproduce:

  1. Have 3+ ContentViews each with a HibridWebViewControl component
  2. Add some buttons to change the content views in the page to navigate through the webviews
  3. Navigate fast from contentView1 to contentView3 to show the last webview passing over the others.

expected: last webview is shown, no crashes

current:

Cannot access a disposed object.
Object name: 'Android.Webkit.WebView'.
at Java.Interop.JniPeerMembers.AssertSelf (Java.Interop.IJavaPeerable self) [0x00029] in <26521a5118b44c858c385715922b9d5d>:0
at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualObjectMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x00000] in <26521a5118b44c858c385715922b9d5d>:0
at Android.Webkit.WebView.get_Url () [0x0000a] in <4ccdb3137d974856b786e1aeebbfbab6>:0
at Plugin.HybridWebView.Droid.HybridWebViewRenderer.b__35_0 () [0x0000c] in <2f2d06da51e84164a0ac7ab59cb79a28>:0
at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <4ccdb3137d974856b786e1aeebbfbab6>:0
at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00009] in <4ccdb3137d974856b786e1aeebbfbab6>:0
at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.44(intptr,intptr)

I use the webview in an own VideoPlayer component to reproduce video:

public sealed class VideoPlayer : Grid, IDisposable
{
    private HybridWebViewControl _webPlayer;


    public static readonly BindableProperty VideoUrlProperty = BindableProperty.Create(nameof(VideoUrl), typeof(Uri), typeof(VideoPlayer), null, BindingMode.TwoWay);
    

    public Uri VideoUrl
    {
        get => (Uri) GetValue(VideoUrlProperty);
        set => SetValue(VideoUrlProperty, value);
    }

    public static readonly BindableProperty AutoPlayProperty = BindableProperty.Create(nameof(AutoPlay), typeof(bool), typeof(VideoPlayer), false, BindingMode.TwoWay);

    public bool AutoPlay
    {
        get => (bool)GetValue(AutoPlayProperty);
        set => SetValue(AutoPlayProperty, value);
    }

    public static readonly BindableProperty VideoLoadedCommandProperty = BindableProperty.Create(nameof(VideoLoadedCommand), typeof(ICommand), typeof(VideoPlayer));
    public ICommand VideoLoadedCommand
    {
        get => (ICommand)GetValue(VideoLoadedCommandProperty);
        set => SetValue(VideoLoadedCommandProperty, value);
    }

    public VideoPlayer()
    {
        _webPlayer = new HybridWebViewControl
        {
            BackgroundColor = Color.Transparent,
            VerticalOptions = LayoutOptions.FillAndExpand,
            HorizontalOptions = LayoutOptions.FillAndExpand
        };
        Children.Add(_webPlayer);

        _webPlayer.OnNavigationCompleted += WebPlayer_Navigated;

        VideoLoadedCommand = new Command(OnVideoLoaded);
    }

    public void OnVideoLoaded()
    {
        if (AutoPlay)
        {
            Play();
        }
    }

    public void Play()
    {
        _webPlayer.InjectJavascriptAsync("document.getElementsByTagName('video')[0].play();");
    }

    public void Pause()
    {
        _webPlayer.InjectJavascriptAsync("document.getElementsByTagName('video')[0].pause();");
    }

    private void WebPlayer_Navigated(object sender, string e)
    {
        _webPlayer.InjectJavascriptAsync(@"document.getElementsByTagName('video')[0].pause();
                    document.getElementsByTagName('video')[0].style.backgroundColor='transparent';
                    document.getElementsByTagName('video')[0].style.width='100%';
                    document.getElementsByTagName('body')[0].style.backgroundColor='transparent';");

        VideoLoadedCommand?.Execute(null);
    }

    public void OpenVideo(object sender = null, EventArgs e = null)
    {
        Children.Remove(_webPlayer);
        Children.Add(_webPlayer);

        _webPlayer.Source = VideoUrl.AbsoluteUri;
        _webPlayer.HorizontalOptions = LayoutOptions.FillAndExpand;
        _webPlayer.VerticalOptions = LayoutOptions.FillAndExpand;
    }

    public void CloseVideo(object sender = null, EventArgs e = null)
    {
        Dispose();
    }

    public void Dispose()
    {
        try
        {
            _webPlayer.OnNavigationCompleted -= WebPlayer_Navigated;
            Children.Clear();                
            _webPlayer?.Dispose();
            _webPlayer = null;                
        }
        catch (Exception exception)
        {
            Debug.WriteLine(exception.Message+exception.StackTrace);
        }
    }
}

Maybe the solution proposed here can be helpful:

xamarin/Xamarin.Forms#6286

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions