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>
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章