Android-WebView使用

开发中使用WebView加载url、html标签必不可少,比如广告、活动界面通过WebView加载具有实效性。下面介绍WebView使用方法。

webView.loadUrl(url);

loadUrl(url)这样可以直接加载网页,但此时是通过手机浏览器打开的网页,如果要使用WebView直接打开则需设置WebViewClient。

webView.setWebViewClient(new WebViewClient());

有关WebViewClient下面再详细介绍。

对于加载Url注意如下:
  1、如果是在线网址记得添加网络访问权限
  2、在线网址中,如果要使用webview打开,记得设置WebViewClient
  3、打开本地html文件时,是不需要设置WebViewClient,对应的asstes目录的url 为:file:///android_asset/xxxxx*

我们先来看如何根据需求设置webView属性,可以调用WebView.getSettings()获取设置WebView的WebSettings对象,通过WebSettings做属性配置,各配置说明如下:

        WebSettings webSettings = webView.getSettings();
        //设置开启javascript支持
        webSettings.setJavaScriptEnabled(true);
        //设置支持缩放
        webSettings.setSupportZoom(true);
        //开启缩放工具(会出现放大缩小的按钮)
        webSettings.setBuiltInZoomControls(true);
        //WebView两种缓存(网页、H5)方式,此处网页不缓存
        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
        //允许JS打开新窗口(默认false)
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        //打开本地缓存供JS调用
        webSettings.setDomStorageEnabled(true);
        //H5缓存内存大小(已过时,不必设置已可自动管理)
        //webSettings.setAppCacheMaxSize(1024 * 1024 * 8);
        //H5缓存路径
        String absolutePath = getApplicationContext().getCacheDir().getAbsolutePath();
        //H5缓存大小
        webSettings.setAppCachePath(absolutePath);
        //是否允许WebView访问内部文件(默认true)
        webSettings.setAllowFileAccess(true);
        //支持存储H5缓存
        webSettings.setAppCacheEnabled(true);
        //启动概述模式浏览界面,当页面宽度超过WebView显示宽度时,缩小页面适应WebView(默认false) 
        webSettings.setLoadWithOverviewMode(true);
        //支持手势缩放(如webView中需要手动输入用户名、密码等,则webview必须设置支持获取手势焦点)
        webView.requestFocusFromTouch();
        // 清除缓存
        webView.clearCache(true);
        // 清除缓存防止登录上次的账号
        CookieManager.getInstance().removeAllCookie();
Java调用JavaScript

java调用JavaScript中的函数很简单,只需要执行如下代码即可:

webView.loadUrl("javascript:toast()");

toast()是JS中方法。

JavaScript调用Java

三个步骤:
  1.调用WebSettings的setJavaScriptEnabled方法使支持JavaScript调用。
  2.调用WebView的addJavascriptInterface方法将应用中的Java对象暴露给JavaScript;
  3.在JavaScript脚本中调用步骤二暴露出来的Java对象的方法。

在webView.addJavascriptInterface(new JsBradge(), "android");实现;其中JsBradge()中是申明了JS可调用的本地方法,“android”是与JS协商的对象名称,JS端可通过android.toastMessage(" ")调用Java方法。
注:如下需加上@JavascriptInterface注解,避免引起WebView远程代码执行漏洞。

    public class JsBradge {
        @JavascriptInterface
        public void toastMessage(String message) {
            Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
        }
    }
WebViewClient

WebViewClient可以拿到WebView在访问网络各个阶段的回调,包括加载前后,失败等(以下注释来源"启舰"博客)

/** 
 * 在开始加载网页时会回调 
 */  
public void onPageStarted(WebView view, String url, Bitmap favicon)   
/** 
 * 在结束加载网页时会回调 
 */  
public void onPageFinished(WebView view, String url)  
/** 
 * 拦截 url 跳转,在里边添加点击链接跳转或者操作 
 */  
public boolean shouldOverrideUrlLoading(WebView view, String url)  
/** 
 * 加载错误的时候会回调,在其中可做错误处理,比如再请求加载一次,或者提示404的错误页面 
 */  
public void onReceivedError(WebView view, int errorCode,String description, String failingUrl)  
/** 
 * 当接收到https错误时,会回调此函数,在其中可以做错误处理 
 */  
public void onReceivedSslError(WebView view, SslErrorHandler handler,SslError error)  
/** 
 * 在每一次请求资源时,都会通过这个函数来回调 
 */  
public WebResourceResponse shouldInterceptRequest(WebView view,  String url) {  
    return null;  
}  

以上可以根据需求做相应处理,其中shouldOverrideUrlLoading方法会在加载超链接时回调过来,当需要WAP与原生互调等劫持URL时用到,重写该方法然后return true即可,当不需要劫持在else中重新loadUrl(url)即可。

            // 当点击链接时,希望覆盖而不是打开新窗口
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                // showProgressDlg();
                // 拦截抢购商品,跳回APP抢购商品详情
                if (url.contains("proId") && url.contains("qgDetail.html")) {

                    String actid = url.split("\\?")[1].split("&")[0].split("=")[1];

                    ActivityController.startActProductDetailActivity(WebActivity.this, actid, "");

                } else if (url.contains("goodDetail.html") && url.contains("proId")) {

                    String id = url.split("\\?")[1].split("&")[0].split("=")[1];

                    ActivityController.startGoodsDetailActivity(WebActivity.this, id);
                } else {
                    view.loadUrl(url);
                }
                return true;
            }
WebChromeClient

可以在其中加载进度条,获取链接的标题等方法。

/**
 * 当网页调用alert()来弹出alert弹出框前回调,用以拦截alert()函数
 */
public boolean onJsAlert(WebView view, String url, String message,JsResult result)
/**
 * 当网页调用confirm()来弹出confirm弹出框前回调,用以拦截confirm()函数
 */
public boolean onJsConfirm(WebView view, String url, String message,JsResult result)
/**
 * 当网页调用prompt()来弹出prompt弹出框前回调,用以拦截prompt()函数
 */
 public boolean onJsPrompt(WebView view, String url, String message,String defaultValue, JsPromptResult result) 
 /**
 * 打印 console 信息
 */
 public boolean onConsoleMessage(ConsoleMessage consoleMessage)
 /**
 * 通知程序当前页面加载进度
 */
 public void onProgressChanged(WebView view, int newProgress)

下面附上我项目里的一段代码,加载进度条跟获取Title:

            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                super.onProgressChanged(view, newProgress);
                if (newProgress == 100) {
                    progressBar.setVisibility(View.GONE);
                } else {
                    if (progressBar.getVisibility() == View.GONE)
                        progressBar.setVisibility(View.VISIBLE);
                    progressBar.setProgress(newProgress);
                }
            }

            @Override
            public void onReceivedTitle(WebView view, String title) {
                setActivityTitle(title);
            }
webView加载html

当后台返回不是url而是一连串的html标签时,可以通过

webView.loadDataWithBaseURL(null, html , "text/html", "UTF-8", "");

之前可以设置:

            //水平不显示滚动条
            webView.setHorizontalScrollBarEnabled(false);
            //垂直不显示滚动条
            webView.setVerticalScrollBarEnabled(false); 

            //初始化压缩比例
            webView.setInitialScale(50);
            // webview自适应屏幕尺寸
            webView.getSettings().setSupportZoom(true);
            webView.getSettings().setUseWideViewPort(true);
            webView.getSettings().setLoadWithOverviewMode(true);
            //设置图片显示方式
            webView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);

            // 设置背景色
            //webView.setBackgroundColor(0);

            webView.getSettings().setDefaultTextEncodingName("UTF-8");
            //设置图片最大尺寸,高度自适应;文字颜色、字体大小、行高、首行缩进两个字符
            // 包含去除img style 的js代码
            String head = "  "
                    + "";

            html = head + "" + html + ""
                    + "";
回退事件处理

当回退时,若不监听回退键点击返回时不会回退到上一web界面,而是直接结束当前Activity,通过canGoBack判断是否可回退,goBack进行回退。代码如下:

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
            if (webView.copyBackForwardList().getItemAtIndex(webView.copyBackForwardList().getSize() - 1).getUrl().contains("activity/201412/act_common.html")) {
                //解决活动重定向无法回退到原生界面
                return super.onKeyDown(keyCode, event);
            } else {
                webView.goBack();
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

以上你看到copyBackForwardList方法,这个是为了解决重定向可以正确退出当前Activity而设置。
先说下问题,当你loadUrl(url1)时,web端将url1更换成了url2,所以显示出来的是url2界面。webview中copyBackForwardList是专门用来管理url栈的,但此时,不光url2入栈,url1也入栈了,所以当在url2界面时,canGoBack返回的也是true,当按回退键时就会回到url1(不会显示)然后马上又回到url2界面,这就是按回退无法finish当前Activity而陷入重新加载url2界面的原因和解决办法。

注意在拥有WebVie的Activity中需要在onDestory方法中销毁webView以防内存泄漏,代码如下:

    @Override
    protected void onDestroy() {
        //销毁webview,避免内在泄漏
        if (webView != null) {
            //移除webView确保Detach
            ViewGroup parent = (ViewGroup) webView.getParent();
            if (parent != null) {
                parent.removeView(webView);
            }
            webView.removeAllViews();
            webView.clearHistory();
            webView.destroy();
            webView = null;
        }
        super.onDestroy();
    }

参考:

WebView使用详解(二)——WebViewClient与常用事件监听
《Android高级进阶》——顾浩鑫/著

你可能感兴趣的:(Android-WebView使用)