WebView 用例

1. 使用 WebView 加载 HTML 四种方式

//方式1:直接加载服务器对应的 URL
webView.loadUrl("http://baidu.com");

//方式2:加载开发项目资源文件夹下的 HTML 文件 
webView.loadUrl("file:///android_asset/test.html");

//方式3:加载手机 sdcard 上的 HTML 文件
webView.loadUrl("content://com.ansen.webview/sdcard/test.html");

//方式4 使用 WebView 直接解析并显示 HTML 代码
webView.loadDataWithBaseURL(null
        ,"<html>
            <head>
                <title> 欢迎 </title>
            </head>" +
            "<body><h2>你可以使用 WebView 解析 HTML 源码</h2>
            </body>
        </html>"
        , "text/html" 
        , "utf-8"
        , null);

2. WebViewClient与WebChromeClient区别

WebViewClient主要帮助WebView处理各种通知、请求事件的,有以下常用方法:

  • onPageFinished 页面请求完成
  • onPageStarted 页面开始加载
  • shouldOverrideUrlLoading 拦截url
  • onReceivedError 访问错误时回调,例如访问网页时报错404,在这个方法回调的时候可以加载错误页面。

WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等,有以下常用方法。

  • onJsAlert webview不支持js的alert弹窗,需要自己监听然后通过dialog弹窗
  • onReceivedTitle 获取网页标题
  • onReceivedIcon 获取网页icon
  • onProgressChanged 加载进度回调

3. WebSettings 常用设置

webSettings.setJavaScriptEnabled //是否允许使用 JS
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);//设置缓存方式,共有四种可选
        - LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
        - LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
        - LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
        - LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
webSettings.setBuiltInZoomControls(false); // 是否使用内置缩放机制
webSettings.setDisplayZoomControls(true);  // 是否显示内置缩放控件

4. WebView 官方文档介绍

https://developer.android.google.cn/reference/android/webkit/WebView

5. 使用 WebView 需要权限

<uses-permission android:name="android.permission.INTERNET" />

6. 参考文档

https://www.jianshu.com/p/a6f7b391a0b8
https://blog.csdn.net/lowprofile_coding/article/details/77928614

7. WebView 示例代码

  • MainActivity

    package com.demo.thorn.webviewdemo;
    
    import android.graphics.Bitmap;
    import android.support.v7.app.AlertDialog;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.KeyEvent;
    import android.view.View;
    import android.webkit.JavascriptInterface;
    import android.webkit.JsResult;
    import android.webkit.WebChromeClient;
    import android.webkit.WebSettings;
    import android.webkit.WebView;
    import android.webkit.WebViewClient;
    import android.widget.ProgressBar;
    import android.widget.Toast;
    
    public class MainActivity extends AppCompatActivity {
            private WebView webView;
            private ProgressBar progressBar;
    
        private final static int KIND_1 = 1;
        private final static int KIND_2 = 2;
        private final static int KIND_3 = 3;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            progressBar= findViewById(R.id.progressbar);//进度条
            webView =findViewById(R.id.webview);
    
            initWebView(KIND_1);//加载 asset 文件夹下 html
            //initWebView(KIND_2);//加载 url
            //initWebView(KIND_3);//使用 webview 示 html
        }
    
        private void initWebView(int loadKind) {
            initWebViewSettings();
            webView.addJavascriptInterface(this,"android");//添加js监听 这样 html 就能调用客户端
            webView.setWebChromeClient(webChromeClient);//处理 JS 的弹窗操作
            webView.setWebViewClient(webViewClient);//处理 JS 返回的结果
    
    
            //选择加载模式
            switch (loadKind){
                case KIND_1:
                    webView.loadUrl("file:///android_asset/test.html");
                    break;
                case KIND_2:
                    webView.loadUrl("http://www.baidu.com/");
                    break;
                case KIND_3:
                    webView.loadDataWithBaseURL(null,"<html><head><title> Welcome </title></head>" +
                    "<body><h2>This is Your Body</h2></body></html>", "text/html" , "utf-8", null);
                    break;
                default:
                    break;
            }
        }
    
        private void initWebViewSettings() {
            WebSettings webSettings= webView.getSettings();
    
            webSettings.setJavaScriptEnabled(true);//允许使用js
    
            /**
             * LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
             * LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
             * LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
             * LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
             */
            webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);//不使用缓存,只从网络获取数据.
    
            //支持屏幕缩放
            webSettings.setSupportZoom(true);
            webSettings.setBuiltInZoomControls(true);
    
            //不显示webview缩放按钮
            webSettings.setDisplayZoomControls(false);
        }
    
    
        //WebViewClient主要帮助WebView处理各种通知、请求事件
    
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {//页面开始加载
                progressBar.setVisibility(View.VISIBLE);
            }
    
            @Override
            public void onPageFinished(WebView view, String url) {//页面加载完成
                progressBar.setVisibility(View.GONE);
            }
    
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
    
                Log.i("jin","拦截 url:"+url);
                if(url.equals("http://www.google.com/")){
                    Toast.makeText(MainActivity.this,"国内不能访问google,拦截该 url ",Toast.LENGTH_LONG).show();
                    return true;//表示我已经处理过了
                }
                return super.shouldOverrideUrlLoading(view, url);
            }
        };
    
        //WebChromeClient 主要辅助 WebView 处理 Javascript 的对话框、网站图标、网站 title 、加载进度等
        private WebChromeClient webChromeClient=new WebChromeClient(){
            //不支持js的alert弹窗,需要自己监听然后通过dialog弹窗
            @Override
            public boolean onJsAlert(WebView webView, String url, String message, JsResult result) {
                AlertDialog.Builder localBuilder = new AlertDialog.Builder(webView.getContext());
                localBuilder.setMessage(message).setPositiveButton("确定",null);
                localBuilder.setCancelable(false);
                localBuilder.create().show();
    
                //注意:
                //必须要这一句代码:result.confirm()表示:
                //处理结果为确定状态同时唤醒WebCore线程
                //否则不能继续点击按钮
                result.confirm();
                return true;
            }
    
            //获取网页标题
            @Override
            public void onReceivedTitle(WebView view, String title) {
                super.onReceivedTitle(view, title);
                Log.i("jin","网页标题:"+title);
            }
    
            //加载进度回调
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                progressBar.setProgress(newProgress);
            }
        };
    
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            Log.i("jin","是否有上一个页面:"+webView.canGoBack());
            if (webView.canGoBack() && keyCode == KeyEvent.KEYCODE_BACK){//点击返回按钮的时候判断有没有上一页
                webView.goBack(); // goBack()表示返回webView的上一页面
                return true;
            }
            return super.onKeyDown(keyCode,event);
        }
    
        /**
         * JS 调用 android 的方法
         * @param str
         * @return
         */
        @JavascriptInterface //仍然必不可少
        public void  getClient(String str){
            Log.i("jin","客户端接收到了数据:"+str);
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
    
            //释放资源
            webView.destroy();
            webView=null;
        }
    }
    
  • activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.demo.thorn.webviewdemo.MainActivity">
    
    
        <WebView
            android:id="@+id/webview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    
        <ProgressBar
            android:id="@+id/progressbar"
            style="@android:style/Widget.ProgressBar.Horizontal"
            android:layout_width="match_parent"
            android:layout_height="3dip"
            android:max="100"
            android:progress="0"
            android:visibility="gone"/>
    
    </android.support.constraint.ConstraintLayout>
    
  • test.html (文件路径:WebViewDemo\app\src\main\assets\test.html)

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8"/>
        <title>这里是标题! </title>
        <style type="text/css">
            dd {
                margin-top:30px; /* 上外边距30像素 */
            }
        </style>
    </head>
    <body>
    <div id="wrap">
        <div id="header"><h1>这里是 Header </h1>
        </div>
        <div id="main">
            <dl>
                <dd><a href="http://www.baidu.com">点击跳转到百度</a></dd>
                <dd><a href="http://www.google.com">点击跳转到google</a></dd>
                <dd>
                    <button id='callback_client' onclick="callBackClient()" type="button">用 js 调用客户端中的方法
                    </button>
                </dd>
            </dl>
        </div>
    </body>
    
    <script>
    
    function callBackClient(){
        alert("调用客户端的 getClient 方法,并传递了数据");//弹窗
        javascript:android.getClient("WebView 中传递的数据");//调用客户端的 getClient 方法,并传递了数据
    }
    </script>
    </html>
    

猜你喜欢

转载自blog.csdn.net/baidu_33221362/article/details/80941373