AndroidWebViewJS 交互经常使用到,最近在做公司项目中和前端调试H5界面时,前端在 JS 中使用 window.open() 来打开新界面,使用 window.close() 关闭界面,而Android的效果是能打开新界面,无法响应关闭的操作,于是经过我的一番摸索,有了这篇文章。

开启 WebView 的多窗口模式很简单,添加下面的设置就可以了

webView.getSettings().setSupportMultipleWindows(true);

这时候如果你设置了 WebChromeClient,就能在 WebChromeClientonCreatWindow()onCloseWindow()的回调,代码如下:

webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
                return super.onCreateWindow(view, isDialog, isUserGesture, resultMsg);
            }

            @Override
            public void onCloseWindow(WebView window) {
                super.onCloseWindow(window);
            }
        });

然并卵,到这一步,你的 WebView 将打不开 H5 界面了。不要担心,下面是最重要的设置操作

@SuppressLint("SetJavaScriptEnabled")
    private void setWebView(WebView webView) {
        //设置webview对象支持解析javascript语句
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setDomStorageEnabled(true);
        //开启多窗口模式
        webView.getSettings().setSupportMultipleWindows(true);
        webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
        // 设置可以支持缩放
        webView.getSettings().setSupportZoom(true);
        // 设置出现缩放工具
        webView.getSettings().setDisplayZoomControls(true);
        //扩大比例的缩放
        webView.getSettings().setUseWideViewPort(true);
        //自适应屏幕
        webView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
        // 解决图片不显示
        webView.getSettings().setBlockNetworkImage(false);
        // 支持自动加载图片
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
                WebView newWebView = new WebView(getContext());
                setWebView(newWebView);
                mBinding.webContainer.addView(newWebView, new FrameLayout.LayoutParams(-1, -1));
        mWebViewList.add(newWebView);
                mCurrentWebView = newWebView;
                //以下的操作应该就是让新的webview去加载对应的url等操作。
                WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
                transport.setWebView(newWebView);
                resultMsg.sendToTarget();
                return true;
            }

            @Override
            public void onCloseWindow(WebView window) {
                super.onCloseWindow(window);
                mBinding.webContainer.removeView(window);
        //获得当前WebView对象,以便后续操作
        int endPosition = mWebViewList.size() - 1;
                if (endPosition >= 0) {
                    mWebViewList.remove(endPosition);
                }
                if (mWebViewList.size() > 0) {
                    mCurrentWebView = mWebViewList.get(mWebViewList.size() - 1);
                }
            }
        });
    }

这是一个递归的方法,在 onCreateWindow() 方法里创建新的 WebView 走相同的设置操作,然后将它添加到 Acivity 界面的容器中,在 onCloseWindow() 的方法中将它移掉,这样就完美响应了 JS 的操作。

如果觉得我的文章对你有用,请随意赞赏