-
Notifications
You must be signed in to change notification settings - Fork 18
Description
Steps to reproduce:
- Have 3+ ContentViews each with a HibridWebViewControl component
- Add some buttons to change the content views in the page to navigate through the webviews
- 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: