Android的WebView完全使用手册(前篇)


笔者叨叨叨..

最近状态总是不对,有心无力的晃着美好的时光,明知道自己很菜但是居然不知道从哪里开始让自己成长。前辈告诉我去研究动画,自定义view,那就慢慢来吧,以后会奉上我的学习心得的。
今天就把最近一直在用的WebView总结下吧,感觉还是有很多干货的。不过写下这个名字,自己都感觉惭愧,但是感觉今天又有很多内容要写,感觉好像要囊括webveiw的实用知识了,再来就算是一种激励,希望自己在写的时候遇到问题能查资料解决,比漫无目的地看一些博客来的有意思多了。
这真的是一个高效的学习方法,毕竟自己还是蛮喜欢在键盘上敲打自己的想法。。。


WebView的基本用法:

WebView,我只知道是Android里面的一个控件:一个可以加载网页的控件。他的用法像一般控件一样 : 先写布局文件,再findViewById。区别就是需要很多Web设置,下面是常用的一些设置 :

WebView的常用API

常用方法:

getSettings() //获取设置WebView的WebSettings对象。

setWebViewClient(WebViewClient client) //设置将接收各种通知和请求的WebViewClient。

setWebChromeClient(WebChromeClient client) //设置chrome处理。

WebSettings getSettings() //获取设置WebView的WebSettings对象。

webView.setOnKeyListener(new View.OnKeyListener() {        // webview can go back
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
                    webView.goBack();
                    return true;
                }
                return false;
            }
        }); //设置网页返回
loadUrl(url); //加载网页

常用的WebSetting API

setAllowFileAccess //启用或禁用WebView访问文件数据

setBlockNetworkImage //是否显示网络图像

setBuiltInZoomControls //设置是否支持缩放

setCacheMode //设置缓冲的模式

setDefaultFontSize //设置默认的字体大小

setDefaultTextEncodingName //设置在解码时时候用的默认编码

setFixedFontFamily  //设置固定使用的字体

setJavaScriptEnabled //设置是否支持Javascript

setLayoutAlgorithm //设置布局方式

setLightTouchEnabled  //设置用鼠标激活被选项

setSupportZoom //设置是否支持变焦

void setWebViewClient(WebViewClient client)  //设置将接收各种通知和请求的WebViewClient。

关于WebSetting里的方法详解博客推荐:
http://blog.csdn.net/a2241076850/article/details/52983939


WebViewClient讲解

WebViewClient就是辅助WebView处理各种通知、请求事件的,具体方法包括:

doUpdateVisitedHistory(WebView view, String url ,boolean isReload)//更新历史记录

onFormResubmission(WebView view, Message dontResend, Message resend)//应用程序重新请求页面数据

onLoadResource(WebView view, String url)//在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次

onPageStarted(WebView view, String url, Bitmap favicon)//这个事件就是开始载入页面调用的,通常我们可以在这个设定一个loading的页面,告诉用户程序在等待网络相应。

onPageFinished(WebView view, String url)//在页面加载结束时调用,同样道理,我们知道一个页面载入完成,于是我们可以关闭loading条,切换程序动作。

onReceivedError(WebView view, int errorCode, String description, String failingUrl)//报告错误信息

onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host,Stirng realm)//获取返回信息授权请求

onScaleChanged(WebView view, float oldScale, float newScale)//WebView 发生改变时调用

onUnhandledKeyEvent(WebView view, KeyEvent event)//key事件未被加载时调用

shouldOverrideUrlLoading//并不是每次都在onPageStarted之前开始调用的,就是说一个新的URL不是每次都经过shouldOverrideUrlLoading的,只有在调用webview.loadURL的时候才会调用。

接下来我们来看一下WebViewClient在开发中的应用:

private class webViewClient extends WebViewClient {

        public boolean shouldOverrideUrlLoading(WebView view, String url) {
        //拦截网页跳转
            if (url != null && url.contains("/user/setting")) {
                Intent intent = new Intent(MainActivity.this, SettingActivity.class);
                startActivity(intent);
                return true;
                //拦截网页拨打电话逻辑,调用本地拨打电话
            }else if (url.startsWith("tel:")) {
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                startActivity(intent);
                return true;
                //拦截网页版支付
            }else if (url.contains("/payment/pay")){
                int currentapiVersion=android.os.Build.VERSION.SDK_INT;
                if (currentapiVersion<19) {
                    String call = "javascript:sumAndOidJava()";
                    webView.loadUrl(call);
                }else {
                    getPriceEvaluateJavascript(webView);
                }
                return true;

            }else {
                //给WebView添加标志位
                currentURL = url;
                if (currentURL.contains("?")) {
                    app_url = "&aa=" + appId + "&bb=" + token;
                } else {
                    app_url = "?aa=" + appId + "&bb=" + token;
                }
                view.loadUrl(currentURL + app_url);
            }
            return true;
        }

        //调用Js的getSumAndOid()方法
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        private void getPriceEvaluateJavascript(WebView webView) {
            webView.evaluateJavascript("getSumAndOid()", new ValueCallback<String>() {
                @Override
                public void onReceiveValue(String value) {
                    String total=value.replace("\"","");
                    if (total.contains("*")) {
                        String price = total.substring(0, total.indexOf("*"));
                        String orderId = total.substring(total.indexOf("*") + 1, total.length());
                        pay(orderId, price);
                    }else {
                        Toast.makeText(MainActivity.this, "网络不给力,请稍后再试", Toast.LENGTH_SHORT).show();
                    }
                   }});

        }


        //拦截网页里面的控件
        @Override
        public void onLoadResource(WebView view, String url) {

            view.loadUrl("javascript:function app_setTop(){document.getElementsByClassName('banner-Bottom')[0].style.display = 'none';}app_setTop();");
            view.loadUrl("javascript:function app_setTop(){document.getElementsByClassName('detial-serve-content')[0].style.display = 'none';}app_setTop();");

                super.onLoadResource(view, url);

        }

        @Override
        public void onReceivedError(WebView view, int errorCode,String description, String failingUrl) {
            super.onReceivedError(view, errorCode, description, failingUrl);
            //这里进行无网络或错误处理,具体可以根据errorCode的值进行判断,做跟详细的处理。

            errorUrl = failingUrl;
            if (loadingDialog.isShowing()) {
                loadingDialog.dismiss();
            }

        }

        @Override
        public void onPageFinished(WebView view, String url) {
        //在这里拦截网页控件不如onLoadResource效果快好
            //view.loadUrl("javascript:function app_setTop(){document.getElementsByClassName('banner-Bottom')[0].style.display = 'none';}app_setTop();");
            //view.loadUrl("javascript:function app_setTop(){document.getElementsByClassName('detial-serve-content')[0].style.display = 'none';}app_setTop();");
            //给网页里面的参数abc和def赋值
            view.loadUrl("javascript:function app_setAa(){abc='" + appId + "';}app_setAa();");
            view.loadUrl("javascript:function app_setBb(){def='" + token + "';}app_setBb();");
        }
    }

WebChromeClient解析

WebChromeClient是辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等 :

onCloseWindow //关闭WebView

onCreateWindow //创建WebView

onJsAlert //处理Javascript中的Alert对话框

onJsConfirm//处理Javascript中的Confirm对话框

onJsPrompt //处理Javascript中的Prompt对话框

onProgressChanged //加载进度条改变

onReceivedlcon //网页图标更改

onReceivedTitle //网页Title更改

onRequestFocus WebView //显示焦点

接下来看看WebChromeClient这个类在实战中的应用:
应用场景:当H5在调用本地相册的时候,没有反应,但是ios,网页,系统浏览器都没有问题就只有android的WebView出来问题,没有办法只有本地处理了:看下面的代码,重写了打开本地文件的openFileChooser方法并做了多方兼容,可以根据开发实际情况选择兼容,最后调用本地的对话框提示用户进行选择拍照还是相册…

private class SelfChromeClient extends WebChromeClient {
        // file upload callback (Android 2.2 (API level 8) -- Android 2.3 (API level 10)) (hidden method)
        public void openFileChooser(ValueCallback<Uri> filePathCallback) {
            handle(filePathCallback);
        }

        // file upload callback (Android 3.0 (API level 11) -- Android 4.0 (API level 15)) (hidden method)
        public void openFileChooser(ValueCallback filePathCallback, String acceptType) {
            handle(filePathCallback);
        }

        // file upload callback (Android 4.1 (API level 16) -- Android 4.3 (API level 18)) (hidden method)
        public void openFileChooser(ValueCallback<Uri> filePathCallback, String acceptType, String capture) {
            handle(filePathCallback);
        }

        // for Lollipop
        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, android.webkit.WebChromeClient.FileChooserParams fileChooserParams) {
            // Double check that we don't have any existing callbacks
            if (mFilePathCallbackArray != null) {
                mFilePathCallbackArray.onReceiveValue(null);
            }
            mFilePathCallbackArray = filePathCallback;
            showDialog();
            return true;
        }

        /**
         * 处理5.0以下系统回调
         *
         * @param filePathCallback
         */
        private void handle(ValueCallback<Uri> filePathCallback) {
            if (mFilePathCallback != null) {
                mFilePathCallback.onReceiveValue(null);
            }
            mFilePathCallback = filePathCallback;
            showDialog();
        }


        /**
         * 显示照片选取Dialog
         */
        public void showDialog() {
            if (ip == null) {
                ip = new ImagePick(MainActivity.this);
            }
            ip.setCancel(new ImagePick.MyDismiss() {
                @Override
                public void dismiss() {
                    handleCallback(null);
                }
            });
            ip.show();
        }

    }

仔细想想貌似就这么多了,可是感觉自己代码一路敲过来,不止这点东西啊,看来是自己没有及时总结,很多解决问题的思路和方法都遗留在时间的长河里,真是可惜,以后又得从头开始百度了…
说于大家——-前车之鉴,后车之师,是为记!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值