Xamarin.Forms Webview OnDetachedFromWindow崩溃了

时间:2018-03-05 09:59:49

标签: xamarin

多次打开渲染器页面时,当返回到最后一页时,它崩溃并记录此异常:

  

System.NotSupportedException:无法激活类型的实例   来自本机句柄的AppZPMC.Droid.Renderers.CustomVideoWebViewRenderer   0xff9919cc(key_handle 0xf2ff0de)。

这是我的代码:

    public class CustomVideoWebViewRenderer : WebViewRenderer
    {
    string url;
    Activity activity;
    WebView webView;
    View customView;
    CustomVideoWebView element;
    FrameLayout.LayoutParams COVER_SCREEN_PARAMS = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);
    FrameLayout fullscreenContainer;
    WebChromeClient.ICustomViewCallback customViewCallback;

    public CustomVideoWebViewRenderer(Context context) : base(context)
    {

    }

    protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
    {
        base.OnElementChanged(e);
        webView = this.Control;
        activity = CrossCurrentActivity.Current.Activity;
        if (e.NewElement != null)
        {
            element = e.NewElement as CustomVideoWebView;
            url = element.VideoUrl;
        }
        if (webView != null)
        {
            InitWebView();
        }
    }

    protected override void OnDetachedFromWindow()
    {
        if (Element == null)
        {
            return;
        }
        base.OnDetachedFromWindow();
        if (Control != null)
        {
            Control.StopLoading();
            Control.LoadUrl("");
            Control.Reload();
            Control.Destroy();
        }
    }

    public void FullScreen(Activity pActivity)
    {
        element.IsFullScreen = true;
        WindowManagerLayoutParams attrs = pActivity.Window.Attributes;
        attrs.Flags |= WindowManagerFlags.Fullscreen;
        attrs.Flags |= WindowManagerFlags.KeepScreenOn;
        pActivity.Window.Attributes = attrs;
        pActivity.RequestedOrientation = Android.Content.PM.ScreenOrientation.Landscape;
    }

    public void SmallScreen(Activity pActivity)
    {
        element.IsFullScreen = false;
        WindowManagerLayoutParams attrs = pActivity.Window.Attributes;
        attrs.Flags &= ~WindowManagerFlags.Fullscreen;
        attrs.Flags &= ~WindowManagerFlags.KeepScreenOn;
        pActivity.Window.Attributes = attrs;
        pActivity.RequestedOrientation = Android.Content.PM.ScreenOrientation.UserPortrait;
    }
    private void InitWebView()
    {
        WebChromeClient wvcc = new WebChromeClient();
        WebSettings webSettings = webView.Settings;
        webSettings.JavaScriptEnabled = true;
        webSettings.SetSupportZoom(false);
        webSettings.CacheMode = CacheModes.NoCache;

        webView.SetWebViewClient(new VideoWebViewClient());

        FrameLayout frameLayout = new FrameLayout(activity.ApplicationContext);
        frameLayout.LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);

        webView.SetWebChromeClient(new VideoWebChromeClient(frameLayout, ShowCustomView, HideCustomView));
        webView.LoadUrl(url);
    }

    private class VideoWebViewClient : WebViewClient
    {
        public override bool ShouldOverrideUrlLoading(WebView view, IWebResourceRequest request)
        {
            view.LoadUrl(request.Url.ToString());
            return base.ShouldOverrideUrlLoading(view, request);
        }
    }

    private class VideoWebChromeClient : WebChromeClient
    {
        FrameLayout frameLayout;
        Action HideCustomView;
        Action<View, ICustomViewCallback> ShowCustomView;

        public VideoWebChromeClient(FrameLayout frameLayout, Action<View, ICustomViewCallback> showCustomView, Action hideCustomView)
        {
            this.frameLayout = frameLayout;
            ShowCustomView = showCustomView;
            HideCustomView = hideCustomView;
        }

        public override View VideoLoadingProgressView => frameLayout;

        public override void OnShowCustomView(View view, ICustomViewCallback callback)
        {
            ShowCustomView(view, callback);
            base.OnShowCustomView(view, callback);

        }

        public override void OnHideCustomView()
        {
            HideCustomView();
            base.OnHideCustomView();
        }
    }

    private void ShowCustomView(View view, WebChromeClient.ICustomViewCallback callback)
    {
        if (customView != null)
        {
            callback.OnCustomViewHidden();
            return;
        }

        FrameLayout decor = (FrameLayout)activity.Window.DecorView;
        fullscreenContainer = new FullscreenHolder(activity.ApplicationContext);
        fullscreenContainer.AddView(view, COVER_SCREEN_PARAMS);
        decor.AddView(fullscreenContainer, COVER_SCREEN_PARAMS);
        customView = view;
        customViewCallback = callback;

        FullScreen(activity);
    }

    private void HideCustomView()
    {
        if (customView == null)
        {
            return;
        }

        FrameLayout decor = (FrameLayout)activity.Window.DecorView;
        decor.RemoveView(fullscreenContainer);
        fullscreenContainer = null;
        customView = null;
        customViewCallback.OnCustomViewHidden();
        webView.Visibility = ViewStates.Visible;

        SmallScreen(activity);
    }

    private class FullscreenHolder : FrameLayout
    {
        public FullscreenHolder(Context ctx) : base(ctx)
        {
            SetBackgroundColor(Color.Black);
        }

        public override bool OnTouchEvent(MotionEvent e)
        {
            return true;
        }
    }
}

这是完整的崩溃日志:

Java.Lang.Error: Exception of type 'Java.Lang.Error' was thrown.
java.lang.Error: Java callstack:
md5ff1c77b81adfd2c553f48967fc623ae5.CustomVideoWebViewRenderer.n_onDetachedFromWindow(Native Method)
md5ff1c77b81adfd2c553f48967fc623ae5.CustomVideoWebViewRenderer.onDetachedFromWindow(CustomVideoWebViewRenderer.java:45)
android.view.View.dispatchDetachedFromWindow(View.java:14595)
android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:3074)
android.view.ViewGroup.removeAllViewsInLayout(ViewGroup.java:4792)
android.view.ViewGroup.removeAllViews(ViewGroup.java:4738)
md5270abb39e60627f0f200893b490a1ade.FragmentContainer.n_onDestroyView(Native Method)
md5270abb39e60627f0f200893b490a1ade.FragmentContainer.onDestroyView(FragmentContainer.java:59)
android.support.v4.app.Fragment.performDestroyView(Fragment.java:2480)
android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1422)
android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1569)
android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:753)
android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2415)
android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2201)
android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2155)
android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2064)
android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:718)
android.os.Handler.handleCallback(Handler.java:742)
android.os.Handler.dispatchMessage(Handler.java:95)
android.os.Looper.loop(Looper.java:157)
android.app.ActivityThread.main(ActivityThread.java:5551)
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:742)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:632)

1 个答案:

答案 0 :(得分:0)

Xamarin.Forms中的常见问题(bug),请看一下:https://github.com/xamarin/Xamarin.Forms/issues/1646,尚未解决:(