WebView

本文详细介绍如何在Android应用中使用WebView加载网页,包括初始化配置、处理网页加载进度、拦截页面跳转及实现与JavaScript交互等核心功能。

初始化视图,可代码创建

        //初始化内置浏览器
        this.webView = (WebView) findViewById(R.id.webWebView);
//        RelativeLayout.LayoutParams relLayoutParams=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
//        this.addContentView(this.webView,relLayoutParams);

 加载网页,并配置属性

this.webView.loadUrl("https://www.hao123.com/");//WebView加载的网页使用loadUrl

        WebSettings webSettings = this.webView.getSettings();//获得WebView的设置
        webSettings.setUseWideViewPort(true);// 设置此属性,可任意比例缩放
        webSettings.setLoadWithOverviewMode(true);//适配
        webSettings.setJavaScriptEnabled(true);  //支持js
        webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);  //设置 缓存模式
        webSettings.setDomStorageEnabled(true);// 开启 DOM storage API 功能
        webSettings.setDatabaseEnabled(true);//开启 database storage API 功能
        webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);//HTTPS,注意这个是在LOLLIPOP以上才调用的
        webSettings.setAppCacheEnabled(true);//开启 Application Caches 功能
        webSettings.setBlockNetworkImage(false);//关闭加载网络图片,在一开始加载的时候可以设置为true,当加载完网页的时候再设置为false

设置网页不跳转到外部浏览器

      //如果不设置WebViewClient,请求会跳转系统浏览器
        this.webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                //返回false,意味着请求过程里,不管有多少次的跳转请求(即新的请求地址),均交给webView自己处理,这也是此方法的默认处理
                //返回true,说明你自己想根据url,做新的跳转,比如在判断url符合条件的情况下,我想让webView加载http://ask.youkuaiyun.com/questions/178242
//                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//                    if (request.getUrl().toString().contains("sina.cn")){
//                        view.loadUrl("http://ask.youkuaiyun.com/questions/178242");
//                        return true;
//                    }
//                }
                return false;
            }
        });


创建进度条

  this.webProgressBar = (ProgressBar) findViewById(R.id.webProgressBar);

关联进度条

  this.webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                //加载的进度
                if (newProgress == 100) {
                    // 网页加载完成
                    webProgressBar.setVisibility(View.GONE);
                } else {
                    // 加载中
                    webProgressBar.setProgress(newProgress);
                }
            }
        });


进度条样式

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:id="@android:id/background">
        <shape>
            <gradient
                android:startColor="@color/colorWhite"
                android:centerColor="@color/colorWhite"
                android:endColor="@color/colorWhite"/>
        </shape>
    </item>

    <item android:id="@android:id/secondaryProgress">
        <clip>
            <shape>
                <gradient
                    android:startColor="@color/colorBlue"
                    android:centerColor="@color/colorBlue"
                    android:endColor="@color/colorBlue"/>
            </shape>
        </clip>
    </item>

    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <gradient
                    android:startColor="@color/colorBlue"
                    android:centerColor="@color/colorBlue"
                    android:endColor="@color/colorBlue"/>
            </shape>
        </clip>
    </item>

</layer-list>




上面是使用WebView中最基础的设置,相信在开发过程中都会进行如上的设置的。

  1. webView.setWebChromeClient(new WebChromeClient() {     
  2.  
  3.      @Override    
  4.  
  5.      public void onProgressChanged(WebView viewint newProgress) { 
  6.  
  7.          //加载的进度 
  8.  
  9.      } 
  10.  
  11.      @Override 
  12.  
  13.      public void onReceivedTitle(WebView view, String title) {    
  14.  
  15.          //获取WebView的标题 
  16.  
  17.      } 
  18.  
  19.     @Override 
  20.  
  21.     public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {     
  22.  
  23.         return super.onJsAlert(view, url, message, result); 
  24.  
  25.         //Js 弹框 
  26.  
  27.     } 
  28.  
  29.     @Override 
  30.  
  31.     public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {    
  32.  
  33.         AlertDialog.Builder b = new AlertDialog.Builder(IllegalQueryActivity.this);     
  34.  
  35.         b.setTitle("删除");     
  36.  
  37.         b.setMessage(message);     
  38.  
  39.         b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {         
  40.  
  41.             @Override         
  42.  
  43.             public void onClick(DialogInterface dialog, int which) {             
  44.  
  45.                 result.confirm();         
  46.  
  47.             }     
  48.  
  49.         });     
  50.  
  51.         b.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {         
  52.  
  53.             @Override         
  54.  
  55.             public void onClick(DialogInterface dialog, int which) {             
  56.  
  57.                 result.cancel();         
  58.  
  59.             }     
  60.  
  61.         });     
  62.  
  63.         b.create().show();     
  64.  
  65.         return true
  66.  
  67.     } 
  68.  
  69. }); 
  70.  
  71. webView.setWebViewClient(new WebViewClient() {     
  72.  
  73.     @Override     
  74.  
  75.     public boolean shouldOverrideUrlLoading(WebView view, String url) {         
  76.  
  77.        //需要设置在当前WebView中显示网页,才不会跳到默认的浏览器进行显示 
  78.  
  79.        return true;    
  80.  
  81.     }     
  82.  
  83.     @Override     
  84.  
  85.     public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { 
  86.  
  87.         super.onReceivedError(view, request, error); 
  88.  
  89.         //加载出错了 
  90.  
  91.     }    
  92.  
  93.     @Override     
  94.  
  95.     public void onPageFinished(WebView view, String url) {         
  96.  
  97.         super.onPageFinished(view, url); 
  98.  
  99.         //加载完成 
  100.  
  101.     } 
  102.  
  103. }); 
  104.  
  105. webView.setDownloadListener(new DownLoadListener());//下载监听 
  106.  
  107. private class DownLoadListener implements DownloadListener {    
  108.  
  109.     @Override    
  110.  
  111.     public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {       
  112.  
  113.     } 
  114.  
  115.  

然后就是WebView跟JS的交互了

  1. webView.addJavascriptInterface(new WebAppInterface(this), "WebJs"); 
  2.  
  3. public class WebAppInterface {  
  4.  
  5.     Context mContext;     
  6.  
  7.     public WebAppInterface(Context c) {         
  8.  
  9.         mContext = c;     
  10.  
  11.     }     
  12.  
  13.     @JavascriptInterface     
  14.  
  15.     public void method() { 
  16.  
  17.     } 
  18.  
  19.  
  20. webView.loadUrl("javascript:jsMethod()");//这是WebView最简单的调用JS的方法  

当activity执行生命周期的时候,这里需要注意的是在onDestroy的时候,需要销毁WebView,不然也会出现内存泄漏的。

  1. @Overrideprotected void onPause() {     
  2.  
  3.     super.onPause();     
  4.  
  5.     if (webView != null) {         
  6.  
  7.         webView.onPause();     
  8.  
  9.     } 
  10.  
  11.  
  12. @Override 
  13.  
  14. protected void onResume() {     
  15.  
  16.     super.onResume();     
  17.  
  18.     if (webView != null) {         
  19.  
  20.         webView.onResume();     
  21.  
  22.     } 
  23.  
  24.  
  25. @Override 
  26.  
  27. protected void onDestroy() {         
  28.  
  29.     if (webView != null) {         
  30.  
  31.         webView.clearCache(true); //清空缓存    
  32.  
  33.         if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {             
  34.  
  35.             if (webViewLayout != null) {                 
  36.  
  37.                 webViewLayout.removeView(webView);             
  38.  
  39.             }             
  40.  
  41.         webView.removeAllViews();             
  42.  
  43.         webView.destroy();         
  44.  
  45.     }else {             
  46.  
  47.         webView.removeAllViews();             
  48.  
  49.         webView.destroy();             
  50.  
  51.         if (webViewLayout != null) {                 
  52.  
  53.             webViewLayout.removeView(webView);            
  54.  
  55.         }         
  56.  
  57.      }   
  58.  
  59.      webView = null;     
  60.  
  61.   }    
  62.  
  63.  

可以看到上面的onDestroy方法中对系统的版本进行了判断,那是因为我在不同的版本中进行了测试,如果低于5.0版本的WebView中,如果先在parent中remove了WebView,那WebView将无法进行destroy了,这样就会造成内存的泄漏,下来你们可以自己去尝试一下这个说法是不是正确的。

现在还遇到的一个问题就是,当WebView嵌套在ScrollView中时,某些机型会出现闪屏的问题,单独WebView的时候是不会出现的,把硬件加速关闭了之后,对用户的体验又不好,所以暂时还未想到比较好的解决方案,所以还是建议不要在ScrollView中嵌套WebView这样的控件。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值