android webview重写第三方H5页面js方法

      需求是这样的,最近通过我们SDK的Webview打开了公司另外一个系统H5支付页面,这个H5页面左上角有个返回按钮,因为不是从我们的H5页面跳转过去的,所以左上角的返回图标执行的windows.history.back(-1);没有生效,商户投诉无法退出。解决办法是1.让这个H5页面点击我们webview暴露出去的一个js事件,点击的时候关闭当前webview Activity,这样成本比较大,另外一个系统也要改,另外这个H5支付系统也给其他系统调用,不太现实。 2.重写H5的windows.history.back(-1);事件,让用户点击的时候能够关闭当前Activity,但是要注意一点,这个H5页面有些情况是需要通过这个事件返回上个页面的,所以要加个判断

if (webView.canGoBackOrForward(step)),能否返回,能返回还是继续执行返回上个页面,不能全盘替换。好,下面给出代码。

  

     

/**
     * onCreate方法.
     *
     * @param savedInstanceState 无
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(Utils.getResourceId(Utils.packageName, "layout", "activity_web_view"));

        mWebView = (WebView) findViewById(Utils
                .getResourceId(Utils.packageName, "id", "web_view"));
        WebSettings webset = mWebView.getSettings();
        webset.setJavaScriptEnabled(true);// 表示webview可以执行服务器端的js代码
        webset.setSupportZoom(true);
        webset.setDomStorageEnabled(true);
        webset.setJavaScriptCanOpenWindowsAutomatically(true);//允许js弹出窗口
        mWebView.requestFocus();
        webset.setUseWideViewPort(true);
        webset.setLoadWithOverviewMode(true);
        webset.setSupportZoom(true);
        webset.setBuiltInZoomControls(true);
        //20191022解决net::ERR_CACHE_MISS,19以上不能使用缓存
        if (18 < Build.VERSION.SDK_INT ){
            //18 = JellyBean MR2, KITKAT=19
            webset.setCacheMode(WebSettings.LOAD_NO_CACHE);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            webset.setMixedContentMode(android.webkit.WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
        progressDialog = new ProgressDialog(WebViewActivity.this);
        mWebView.addJavascriptInterface(new JsInterface(this), "mobile");
        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {

                //H5返回支付结果页面去查询支付结果
                if (url.contains("service/showResultPage")) {
                    new AsyncSign(WebViewActivity.this).execute();
                    return;
                }
                //20191119荣耀v20会出现dialog的Unable to add window,加个判断
                if(!isFinishing()&&!progressDialog.isShowing()) {
                    progressDialog.setMessage("加载中,请稍后...");
                    progressDialog.setCanceledOnTouchOutside(false);
                    progressDialog.show();
                }
            }

            @Override
            public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
                // 重写此方法才能够处理在浏览器中的按键事件
                return super.shouldOverrideKeyEvent(view, event);
            }
            //20200623 add 加载这个假页面后触发关闭当前activity
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                shouldOverrideUrlLoadingNew(view,url);
                return super.shouldOverrideUrlLoading(view, url);
            }
            @Override
            public void onPageFinished(WebView view, String url) {
                //20200623 add 重写 windows.history.back(-1)方法,赋值一个假页面
                onPageFinishedNew(view,url);
                // 在页面加载结束时调用
                super.onPageFinished(view, url);
                if(progressDialog!=null&&progressDialog.isShowing())
                {
                    progressDialog.dismiss();
                }
            }


            @Override
            public void onReceivedError(WebView view, int errorCode, String description,
                                        String failingUrl) {
                // 重写此方法可以让webview处理https请求
                super.onReceivedError(view, errorCode, description, failingUrl);
            }

        });
        mWebView.setWebChromeClient(new MyWebChromeClient() );
        mWebView.setPictureListener(new MyPictureListener());
    }

    /**
     * 20191030页面更新 .
     */
    class MyPictureListener implements WebView.PictureListener {
        @Override
        public void onNewPicture(WebView view, Picture arg1) {
            if(progressDialog!=null&&progressDialog.isShowing())
            {
                progressDialog.dismiss();
            }
        }
    }
    //begin  20200623重写history.back(-1)方法,解决指定跳转到H5支付无法返回问题
    /**
     * 自定义的,当js调用history.go时加载的链接,以监听history.go方法的调用
     */
    private final static String CONSTANTS_GO_BACK = "/CONSTANTS_GO_BACK#";
    /**
     * 在WebViewClient对应方法中调用
     * 注:此方法需手动调用,或者使用defaultClient == true
     */
    public void shouldOverrideUrlLoadingNew(WebView webView,String url) {
        if (!StringUtil.isEmpty(url) && url.contains(CONSTANTS_GO_BACK)) {
            int step = -1;
            try {
                //解析js调用history.back时传入的参数
                step = Integer.parseInt(url.split("#")[1]);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (webView.canGoBackOrForward(step)) {
                webView.goBackOrForward(step);
            } else {
                //当没有上一个页面,而js调用了history.go时回调方法
                Utils.returnResultInfo(this, AsyGlobalInfo.CODE_EXIT, "中途退出", null);
                WebViewActivity.this.finish();
            }
        }
    }
    /**
     * 在WebViewClient对应方法中调用
     * 注:此方法需手动调用,或者使用defaultClient == true
     */
    public void onPageFinishedNew(WebView webView,String url) {
        //重写js页面window.history.back方法
//        String script1 = "javascript:(function(){window.history.go = function(index){" +
//                "window.location.href='" + CONSTANTS_GO_BACK + "'+index;" +
//                "}})()";
//        webView.loadUrl(script1);

        //重写js页面goToPreStep方法会出现跳转两次
        //String script1 = "javascript:(function(){goToPreStep= function(){" +
                //"alert(quickStep);"+
                //"}})()";
        //webView.loadUrl(script1);

        //重写js页面window.history.back方法
        String script = "javascript:(function(){window.history.back= function(index){" +
                "window.location.href='" + CONSTANTS_GO_BACK + "'+index;" +
                "}})()";
        webView.loadUrl(script);
    }
    //end
    /**
     * MyWebChromeClient .
     */
    private class MyWebChromeClient extends WebChromeClient {
        /**
         *
         * @param view .
         * @param newProgress .
         */
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            super.onProgressChanged(view, newProgress);
            if(newProgress==100){
                if(progressDialog!=null&&progressDialog.isShowing())
                {
                    progressDialog.dismiss();
                }
            }

        }

    }

         思路比较秒的,webview的onPageFinished重写当前H5页面的window.history.back方法,给当前页面换个新地址

"window.location.href='" + CONSTANTS_GO_BACK + "'+index;",当用户点击回退的时候,当前页面变成了CONSTANTS_GO_BACK 这个假地址,加载页面的时候会触发shouldOverrideUrlLoading,这个事件里就发现是url包含CONSTANTS_GO_BACK这个地址,就可以执行关闭当前Activity了。我也参考了网上的一些资料,整理出来较完整的demo供参考。 
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值