美文网首页
android那些事--WebView拦截使用

android那些事--WebView拦截使用

作者: lucky9322 | 来源:发表于2016-10-31 23:23 被阅读8431次

    WebView最简单的用法就是loadUrl方法.
    常用代码如下.

     demoWv = ((WebView) findViewById(R.id.demoWv));
            WebSettings settings = demoWv.getSettings();
    //        网页中含有JavaScript脚本时,需要调用以下方法,参数为true
            settings.setJavaScriptEnabled(true);
            demoWv.setWebViewClient(new WebViewClient() {
                @Override
                public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
    //                是否使用第三方浏览器 返回true不调用 返回false调用
                    return true;
                }
            });
            demoWv.loadUrl("https://www.baidu.com");
    
    这里写图片描述

    WebView拦截请求

    WebView调用loadUrl后,会首先根据传入URL获取响应,然后再将响应显示到页面上,这就是WebView的原理.根据这个原理,那么我们可以在获取响应过程中重新改变请求URL或者直接将响应替换.
    而具体的替换在WebViewClient的:

    WebResourceResponse shouldInterceptRequest(
    WebView view,WebResourceRequest request
    )
    

    这个方法中,该方法用于根据请求去获取响应,如果返回null,那么android会根据请求去获取响应并返回,但是如果你重写了该方法并返回了响应,那么WebView就会使用你的响应数据.其中WebResourceRequest封装了请求,WebResourceResponse封装了响应.

    使用静态响应

    既然知道了原理,就可以写个demo测试一下

            demoWv = ((WebView) findViewById(R.id.demoWv));
            WebSettings settings = demoWv.getSettings();
    //        网页中含有JavaScript脚本时,需要调用以下方法,参数为true
            settings.setJavaScriptEnabled(true);
            demoWv.setWebViewClient(new WebViewClient() {
                @Override
                public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
    //                是否使用第三方浏览器 返回true不调用 返回false调用
                    return true;
                }
                @Override
                public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
                    String result = "<html>\n" +
                            "<title>千度</title>\n" +
                            "<body>\n" +
                            "<a href=\"www.taobao.com\">千度</a>,比百度知道的多10倍\n" +
                            "</body>\n" +
                            "<html>";
                    WebResourceResponse response = new WebResourceResponse("text/html",
                            "utf-8",
                            new ByteArrayInputStream(result.getBytes()));
                    return response;
                }
            });
            demoWv.loadUrl("https://www.baidu.com");
    
    这里写图片描述

    使用网络资源响应

    shouldInterceptRequest方法API还有介绍,该方法是在非UI线程中,所以当需要与View系统交互时需要小心.既然时非UI线程中,那么我们可以放在其中做网络请求.比如可以可以去www.importnew.com的响应数据,将百度替换为importnew.

       @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            demoWv = ((WebView) findViewById(R.id.demoWv));
            WebSettings settings = demoWv.getSettings();
    //        网页中含有JavaScript脚本时,需要调用以下方法,参数为true
            settings.setJavaScriptEnabled(true);
            demoWv.setWebViewClient(new WebViewClient() {
                @Override
                public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
    //                是否使用第三方浏览器 返回true不调用 返回false调用
                    return true;
                }
                @Override
                public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
                    return getWebRes();
                }
            });
            demoWv.loadUrl("https://www.baidu.com");
        }
    
        private WebResourceResponse getWebRes() {
            StringBuilder stringBuilder = new StringBuilder();
            BufferedReader bufferedReader = null;
            try {
                URL url = new URL("http://www.importnew.com/");
                HttpURLConnection httpURLConnection = (HttpURLConnection) url
                        .openConnection();
    //            连接主机超时时间
                httpURLConnection.setConnectTimeout(10 * 1000);
    //            设置从主机读取数据超时
                httpURLConnection.setReadTimeout(40 * 1000);
                bufferedReader = new BufferedReader(new
                        InputStreamReader(httpURLConnection
                        .getInputStream()));
                String line = "";
                while ((line = bufferedReader.readLine()) != null) {
                                stringBuilder.append(line);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                if (bufferedReader!=null){
                    try {
                        bufferedReader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
               
                 }
            }
            WebResourceResponse webResourceResponse = null;
            webResourceResponse=new WebResourceResponse("text/html",
                    "utf-8",
                    new ByteArrayInputStream(stringBuilder.toString().getBytes()));
            return webResourceResponse;
        }
    
    这里写图片描述

    注意:WebView中调用的每个请求都会经过那个拦截器,所以如果一个页面中又有超链接,那么依然会经过那么拦截器.所以上面的Importnew中有些图片没有加载出来.因为是以文本形式响应的,并且是以utf-8做为编码的,所以有时候会出现乱码.

    应用

    在实际应用中,最好时先判断要加载的URL是否需要拦截,如果不是的话,可以以然交给WebView去实现.

    相关文章

      网友评论

          本文标题:android那些事--WebView拦截使用

          本文链接:https://www.haomeiwen.com/subject/fmaputtx.html