• Android WebView使用总结


    #.简介:

        WebView是Android提供的用来展示展示web页面的View,内部使用webkit浏览器引擎(一个轻量级的浏览器引擎),除了展示Web页面外,还可与Web页面内的JS脚本交互调用。

    #一、WebView常用方法

    1.加载Url或资源的方法

    1. //方式1:加载指定Url,可以指向网络资源,也可以是本地资源。这是最常用的加载方法。
    2.         webView.loadUrl("百度一下,你就知道");
    3.         webView.loadUrl("file:///xxx/xxx/test.html");
    4.         //方式2:加载内容片段
    5.         loadData(String data, String mimeType, String encoding);
    6.         loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl));

    2.生命周期相关方法

    1.         /*2.生命周期相关方法
    2.             一般会根据所在页面的生命周期变化,来调用以下相关方法*/
    3.         //2.1激活WebView实例为活跃状态,能正常执行网页的响应
    4.         webView.onResume();
    5.         //2.2通知WebView实例的内核暂停所有的动作,如页面解析、插件加载、JavaScript脚本执行等。
    6.         //一般当页面被失去焦点被切换到后台不可见状态,需要执行onPause
    7.         webView.onPause();
    8.         //2.3暂停应用中所有webview的layout、parsing、javascriptTimer等,降低CPU功耗。
    9.         //一般当应用被切换到后台时,调用该方法,作用于所有WebView
    10.         webView.pauseTimers();
    11.         //2.4恢复调用pauseTimers()后被暂停的状态
    12.         webView.resumeTimers();
    13.         //2.5销毁WebView实例
    14.         //注意:为避免出错,要先把WebView从所在View树上移除,再销毁WebView实例
    15.         rootLayout.removeView(webView);
    16.         webView.destroy();

    3.页面前进、后退

    1.         /*3.页面前进、后退*/
    2.         //是否可以后退
    3.         webview.canGoBack();
    4.         //后退一页
    5.         webview.goBack();
    6.         //是否可以前进
    7.         webview.canGoForward();
    8.         //前进一页
    9.         webview.goForward();
    10.         //以当前的index为起始点前进或者后退到历史记录中指定的steps
    11.         //如果steps为负数则为后退,正数则为前进
    12.         webview.goBackOrForward(steps);

    4.事件拦截

    1.         /*4.事件拦截
    2.             有很多相关的方法,下面是几个例子*/
    3.         //例如覆写按键事件,onKeyDown()/onKeyUp()
    4.         @Override
    5.         public boolean onKeyDown(int keyCode, KeyEvent event) {
    6.             //示例:点击返回按钮后,默认是触发Activity的finish。若需要触发网页回退,可以添加代码:
    7.             if ((keyCode == KEYCODE_BACK) && mWebView.canGoBack()) {
    8.                 mWebView.goBack();
    9.                 return true;
    10.             }
    11.             return super.onKeyDown(keyCode, event);
    12.         }
    13.         @Override
    14.         public boolean onKeyUp(int keyCode, KeyEvent event) {
    15.             return super.onKeyUp(keyCode, event);
    16.         }

    5.设置回调接口

    1.         /*5.设置回调接口
    2.             有很多可设置的接口,下面是个例子*/
    3.         //设置下载监听接口
    4.         webView.setDownloadListener(new DownloadListener() {
    5.             @Override
    6.             public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
    7.                
    8.             }
    9.         });

    6.其它方法

    1.     /*6.其它方法*/
    2.     //刷新页面(当前页面的所有资源都会重新加载)
    3.     webView.reload();
    4.     //停止加载
    5.     webView.stopLoading();
    6.     //清除整个应用中WebView网页访问留下的缓存
    7.     webView.clearCache(true);
    8.     //清除对应WebView访问的历史记录
    9.     webview.clearHistory();
    10.     //清除当前WebView自动完成填充的表单数据(并不会清除WebView存储到本地的数据)
    11.     webview.clearFormData();

    #二、常用的辅助类:WebSetting/WebViewClient/ChromeWebviewClient

        WebView内部的WebSetting对象负责管理WebView的参数配置;
        WebViewClient负责处理WebView的各种请求和通知事件,在对应事件发生时会执行WebViewClient的对应回调;
        ChromeWebviewClient 辅助Webview处理与JS一些交互功能,主要是提供一些标准的回调方法,当JS调用相关方法时会触发对应回调。    

    ##1. 通过WebSetting设置参数

        WebView内部的WebSetting对象负责管理WebView的配置,WebSetting提供了一系列方法来供开发者来做配置。
        以下将这些参数分为了三大类:显示相关的、缓存和存储相关的、其它相关,在下面代码和注释中详细列举出了。
    其中 缓存模式,一共可设置四种:
            LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
            LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
            LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
            LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
    1. //0.获取WebSettings对象,通过WebView的getSettings()
    2. WebSettings webSettings = getSettings();
    3. if (null != webSettings) {
    4.     /*1.显示效果相关设置:页面缩放、页面自适应等等*/
    5.     //1.1设置自适应屏幕,两者合用
    6.     webSettings.setLoadWithOverviewMode(true); //缩放至屏幕的大小
    7.     webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小
    8.     //1.2缩放操作
    9.     //支持缩放,默认为true。是下面几项设置的的前提
    10.     webSettings.setSupportZoom(true);
    11.     //设置内置的缩放控件。若为false,则该WebView不可缩放
    12.     webSettings.setBuiltInZoomControls(true);
    13.     webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件
    14.     //1.3其它
    15.     webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片
    16.     webSettings.setSupportMultipleWindows(false);//是否支持多窗口
    17.     //设置布局,会引起WebView的重新布局(relayout),默认值NARROW_COLUMNS
    18.     webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
    19.     /*2.缓存、数据存储、缓存加载相关设置*/
    20.     //2.1缓存相关
    21.     /* webSettings.setCacheMode()可设置缓存模式,一共可设置四种缓存模式:
    22.         LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
    23.         LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
    24.         LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
    25.         LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
    26.         可结合使用(离线加载)
    27.         if (有网络) {
    28.             webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);//根据cache-control决定是否从网络上取数据。
    29.         } else {
    30.             webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);//没网,则优先从本地获取,即离线加载
    31.         }*/
    32.     //设置缓存的模式,这里设置的模式为默认模式,即根据cache-control决定是否从网络上取数据
    33.     webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
    34.     //开启应用缓存,默认值false
    35.     webSettings.setAppCacheEnabled(true);
    36.     //设置应用缓存文件路径
    37.     webSettings.setAppCachePath(getContext().getDir("appcache", 0).getPath());
    38.     //设置应用缓存内容的最大值
    39.     webSettings.setAppCacheMaxSize(Long.MAX_VALUE);
    40.     //3.2其它
    41.     //开启数据库存储API功能
    42.     webSettings.setDatabaseEnabled(true);
    43.     //设置数据库的存储路
    44.     webSettings.setDatabasePath(getContext().getDir("databases", 0).getPath());
    45.     webSettings.setAllowFileAccess(true); //设置允许访问文件系统
    46.     webSettings.setDomStorageEnabled(true);//开启DOM存储API功能
    47.     /*3.其它设置*/
    48.     //3.1 js脚本、插件相关设置
    49.     //设置为支持Javascript,此时可与页面中的js脚本交互
    50.     webSettings.setJavaScriptEnabled(true);
    51.     //支持通过JS打开新窗口
    52.     webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
    53.     //3.2加载模式
    54.     //Android5.0开始,WebView默认不支持同时加载Https和Http混合模式
    55.     //此处设置为支持混合模式
    56.     if (Build.VERSION.SDK_INT >= 21) {
    57.         webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
    58.     }
    59.     //3.3其它
    60.     webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式
    61.     webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);  //提高渲染的优先级
    62.     webSettings.setGeolocationEnabled(true);// 启用地理定位
    63.     webSettings.setGeolocationDatabasePath(getContext().getDir("geolocation", 0).getPath());//设置定位的数据库路径
    64.     //设置WebView的用户代理字符串,网页端可获取到该字符串从而判断客户端类型,应该按照与web端约定的规则生成。
    65.     //如果字符串为null或者empty,将使用系统默认值。
    66.     webSettings.setUserAgentString(webSettings.getUserAgentString() + DeviceUtils.getUserAgent());
    67. }

    ##2.设置WebViewClient

        WebViewClient负责处理WebView的各种请求和通知事件,在对应事件发生时会执行WebViewClient的对应回调。例如URL加载重定向、网页开始加载/加载完毕、各种错误通知等。
        常用方法与接收,见以下代码示例与注释。
    1. /**
    2. * 按照doc中注释说明,当WebView不设置WebViewClient时,加载Url时默认会选择系统中合适的Activity来打开该Url。
    3. * 当设置WebViewClient时,加载Url默认会执行到该方法,可在内部做相应处理。
    4. *   返回true时,意味着应用已经拦截并处理了本次加载事务,WebView后继将不再处理;
    5. *   返回false时,意味着应用未拦截本次加载事务,后继WebView将加载该Url
    6. * 注意:POST请求不会触发该方法
    7. *
    8. * 可以在这该方法进行各种判断,例如约定好好各种类型操作的Url格式,解析Url格式和参数
    9. *  来判断是去打开特定Activity执行特定操作,还是加载Url对应网页
    10. * @param view
    11. * @param url
    12. * @return
    13. */
    14. @Override
    15. public boolean shouldOverrideUrlLoading(WebView view, String url) {
    16.     //可以在这里进行各种判断,例如定义好各种url格式,解析url格式和参数
    17.     // 来判断是去打开特定Activity执行特定操作,还是加载url对应网页
    18.     return false;
    19. }
    20. /**
    21. * 当开始加载Url时回调
    22. */
    23. @Override
    24. public void onPageStarted(WebView view, String url, Bitmap favicon) {
    25.     super.onPageStarted(view, url, favicon);
    26. }
    27. /**
    28. * 页面加载完毕时回调
    29. */
    30. @Override
    31. public void onPageFinished(WebView view, String url) {
    32.     super.onPageFinished(view, url);
    33. }
    34. /**
    35. * 在即将加载网络请求之前回调,可拦截返回自定义的资源作为请求结果,让WebView来加载
    36. */
    37. @Override
    38. public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
    39.     return super.shouldInterceptRequest(view, request);
    40. }
    41. /**
    42. * 当WebView显示内容发生放缩时回调
    43. */
    44. @Override
    45. public void onScaleChanged(WebView view, float oldScale, float newScale) {
    46.     super.onScaleChanged(view, oldScale, newScale);
    47. }
    48. /**
    49. * 访问Url出错时回调
    50. */
    51. @Override
    52. public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
    53.     super.onReceivedError(view, request, error);
    54. }
    55. /**
    56. * 当网页加载资源过程中发现SSL错误时回调。
    57. * 可执行的操作:handler.cancel(),取消请求;
    58. *            handler.proceed(),继续请求;
    59. * 默认的逻辑时取消请求。
    60. * @param view
    61. * @param handler
    62. * @param error
    63. */
    64. @Override
    65. public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
    66.     String url = null;
    67.     if (error != null) {
    68.         url = error.getUrl();
    69.     }
    70.     if (!TextUtils.isEmpty(url)) {
    71.         handler.proceed();
    72.     } else {
    73.         super.onReceivedSslError(view, handler, error);
    74.     }
    75. }

    ##3.ChromeWebviewClient

        辅助Webview处理与JS一些交互功能,主要是提供一些标准的回调方法,当JS调用相关方法时会触发对应回调。
        除此之外,还可以获取网页加载进度和网页标题等。
    一些API方法示例:
    1. /**
    2. * 按照doc中注释说明,当WebView不设置WebViewClient时,加载Url时默认会选择系统中合适的Activity来打开该Url。
    3. * 当设置WebViewClient时,加载Url默认会执行到该方法,可在内部做相应处理。
    4. *   返回true时,意味着应用已经拦截并处理了本次加载事务,WebView后继将不再处理;
    5. *   返回false时,意味着应用未拦截本次加载事务,后继WebView将加载该Url
    6. * 注意:POST请求不会触发该方法
    7. *
    8. * 可以在这该方法进行各种判断,例如约定好好各种类型操作的Url格式,解析Url格式和参数
    9. *  来判断是去打开特定Activity执行特定操作,还是加载Url对应网页
    10. * @param view
    11. * @param url
    12. * @return
    13. */
    14. @Override
    15. public boolean shouldOverrideUrlLoading(WebView view, String url) {
    16.     //可以在这里进行各种判断,例如定义好各种url格式,解析url格式和参数
    17.     // 来判断是去打开特定Activity执行特定操作,还是加载url对应网页
    18.     return false;
    19. }
    20. /**
    21. * 当开始加载Url时回调
    22. */
    23. @Override
    24. public void onPageStarted(WebView view, String url, Bitmap favicon) {
    25.     super.onPageStarted(view, url, favicon);
    26. }
    27. /**
    28. * 页面加载完毕时回调
    29. */
    30. @Override
    31. public void onPageFinished(WebView view, String url) {
    32.     super.onPageFinished(view, url);
    33. }
    34. /**
    35. * 在即将加载网络请求之前回调,可拦截返回自定义的资源作为请求结果,让WebView来加载
    36. */
    37. @Override
    38. public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
    39.     return super.shouldInterceptRequest(view, request);
    40. }
    41. /**
    42. * 当WebView显示内容发生放缩时回调
    43. */
    44. @Override
    45. public void onScaleChanged(WebView view, float oldScale, float newScale) {
    46.     super.onScaleChanged(view, oldScale, newScale);
    47. }
    48. /**
    49. * 访问Url出错时回调
    50. */
    51. @Override
    52. public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
    53.     super.onReceivedError(view, request, error);
    54. }
    55. /**
    56. * 当网页加载资源过程中发现SSL错误时回调。
    57. * 可执行的操作:handler.cancel(),取消请求;
    58. *            handler.proceed(),继续请求;
    59. * 默认的逻辑时取消请求。
    60. * @param view
    61. * @param handler
    62. * @param error
    63. */
    64. @Override
    65. public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
    66.     String url = null;
    67.     if (error != null) {
    68.         url = error.getUrl();
    69.     }
    70.     if (!TextUtils.isEmpty(url)) {
    71.         handler.proceed();
    72.     } else {
    73.         super.onReceivedSslError(view, handler, error);
    74.     }
    75. }

    ##4. Cookie相关设置

    1.     //Cookie相关设置
    2.     if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP){
    3.         CookieSyncManager.createInstance(context);
    4.     }
    5.     CookieManager cookieManager = CookieManager.getInstance();
    6.     cookieManager.setAcceptCookie(true);//允许使用Cookie
    7.     //手动同步Cookie信息
    8.     if (Build.VERSION.SDK_INT < 21) {
    9.         CookieSyncManager.getInstance().sync();
    10.     } else {
    11.         CookieManager.getInstance().flush();
    12.     }

    #三、WebView中Java与JS交互的几种方式

    #1. Java调用JS

    ##方法1:使用Webview.loadUrl(“javaScript:【方法名和参数对应的字符串】”);

    注:该方法会导致页面刷新
    示例:
    mWebView.loadUrl( “javascript:callJS()” );
    mWebView.loadUrl( “javascript:callJS("+ 【参数变量】 +")” );

    ##方法2:使用Webview.evaluateJavaScript(“javaScript:【方法名和参数对应的字符串】”);

    注:1.该方法不会导致页面刷新  2.Android4.4之后才能使用该API方法
    示例:
    //注:在 ValueCallback<String>泛型中的参数类型表明JS函数返回值的类型,该示例中为String类型
    mWebView.evaluateJavascript( "javascript:callJS()" , new ValueCallback<String>() { 
         @Override 
         public void onReceiveValue (String value ) { 
             //此处为 js 返回的结果 
        
    });

    #2. JS调用Java

    ##方法1:通过WebView.addJavascriptInterface(【包含JS接口的Java对象】, 【在JS中的对象名称】);

    在JavaScript中映射一个Java对象,该对象包含了各种需要被调用的方法。
    使用步骤:
    1).声明一个Java类,通过 @JavascriptInterface注解来创建各个需要被JS调用的方法
    2).通过 WebView.addJavascriptInterface( 【Java对象】 , “【JS中的对象名称】” )将一个上述Java类对象与 JavaScript中对应名称的对象 建立映射关系
    3).在JS中通过指定名称对象调用相关方法,等于调用被映射的Java对象的方法
    示例:
    1. public class JSInterface{
    2.     @JavascriptInterface
    3.     public void pay(final String json) {
    4.     }
    5.     @JavascriptInterface
    6.     public String getToken() {
    7.         return null;
    8.     }
    9. }
    10. //设置JS接口对应的Java对象
    11. JSInterface jsInterface = new JSInterface();
    12. addJavascriptInterface(jsInterface, "javaObj");
    13. //在JS中,可以用指定的名称"javaObj"来调用Java相应方法

    #方法2:通过在JS中加载url, 触发WebView.shouldOverrideUrlLoadding(WebView view,String url)方法,从而在该方法中根据加载的url字符串做相应的逻辑处理。

    使用步骤:
        1)当JS中进行url加载时,Android中WebViewClient 的回调方法shouldOverrideUrlLoading()会被触发,拦截相应url
        2)在shouldOverrideUrlLoading()对拦截的url做解析,执行需要执行的对应逻辑。

    #方法3:通过在JS中执行各种弹窗操作,来触发WebChromeClient的相应拦截方法,在回调方法中执行需要的逻辑。不推荐该方式,因为这些回调方法在设计上讲,本来不是做这种用途的。

    (其思路与方法2相似,也是通过JS中的操作来触发Java中的回调方法,从而在Java回调方法中执行需要执行的逻辑。只不过方法2是通过加载url,来触发WebViewClient的shouldOverrideUrlLoadding()方法;而方法3是通过各种弹窗操作,来触发WebChromeClient的各种回调方法。)
    使用步骤,与方法2类似:
        1.在JS中调用弹窗,触发WebChromeClient的相应拦截方法
        2.在Java拦截方法中,通过解析传入的字符参数,来执行相应的逻辑。
    JS中常用的弹窗方法由三种:         alert()、confirm()、prompt()
    在WebChromeClient中对应触发的拦截方法为:onJsAlert()、onJsConfirm()、onJsPrompt
  • 相关阅读:
    sql优化及索引失效
    什么是SRRC认证?SRRC认证是什么?
    63基于matlab的生物地理的优化器(BBO)被用作多层感知器(MLP)的训练器。
    人工智能AI知多少?
    Linux系统运维脚本:shell脚本查看一定网段范围在线网络设备的ip地址和不在线的网络设备的数量(查看在线和不在线网络设备)
    NSSCTF做题第9页(2)
    C# 窗口事件
    653 · 添加运算符
    spring mvc中如何设置log4j.xml的配置文件呢?
    从C#到Python手把手教你用Python实现内存扫描获取指定字符串
  • 原文地址:https://blog.csdn.net/u013914309/article/details/125546815