Android開發 WebView的詳解


前言

  WebView 是Android顯示html內容的主要方式,當然TextView也可以加載html內容.但是WebView除了功能更加強大,最重要的是還能調用Html里的JavaScript語言,這才是我們必需學習WebView的原因.

加載內容方式

方式一:加載一個網頁

mWebView.loadUrl("http://www.baidu.com");

方式二:加載應用資源文件內的網頁

mWebView.loadUrl("file:///android_asset/test.html");

需要注意的一點file:///  這里是3條斜杠,這個方式加載本地html,既可以加載網絡地址的圖片,也可以加載本地路徑的圖片

保存在assets目錄的test.html (此html里的圖片為網絡地址)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
    <h1>Android WebView測試</h1>
    <p>下面顯示圖片</p>
    <img src="https://wow.nosdn.127.net/1/wow/wowclassic/JVIX5HPT66L41555957772316.png" alt="圖片加載失敗" width="100%">
</body>
</html>

效果圖:

 

保存在assets目錄的test.html (此html里的圖片為本地路徑)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
<h1>Android WebView測試</h1>
<p>下面顯示圖片</p>
<img src="file:///storage/emulated/0/DCIM/Camera/IMG_20190524_175239.jpg" alt="圖片加載失敗" width="100%">
</body>
</html>

需要注意的一點圖片的路徑前面需要添加 file:///  這里也是3個斜杠. 效果圖一上面一樣,就不展示了.

方式三:加載Html代碼片段

mWebView.loadData(String data,String mimeType, String encoding);

例子:

       String htmlContent = "<h1>Android WebView測試</h1>\n" +
                "<p>下面顯示圖片</p>\n" +
                "<img src=\"https://wow.nosdn.127.net/1/wow/wowclassic/JVIX5HPT66L41555957772316.png\" alt=\"圖片加載失敗\" width=\"100%\">";
        mWebView.loadData(htmlContent, "text/html", "UTF-8");

注意! 這種加載html片段的方式不支持加載本地路徑的圖片,但是支持網絡地址圖片.

方式四 : 加載Html代碼片段,並且支持加載本地圖片與網絡圖片

如果你需要加載html代碼片段,我們一般是選擇這個loadDataWithBaseURL方法.因為功能會更加強大.

 

mWebView.loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String failUrl)

 

解釋下這里的參數

  • 第一個參數 baseUrl 是文件或者圖片加載的相對路徑,這是一個可以細細研究的參數.因為它既可以作用於網絡地址的相對網站地址,也可以作用與本地圖片或者其他文件的來源相對目錄(下面會圍繞這個參數來一一講解)
  • 第二個參數 data是Html的代碼片段
  • 第三個參數 mimeType是文件類型
  • 第四個參數 encoding是字符串編碼
  • 第五個參數 failUrl為歷史Url,一般設置為null

baseUrl參數為空

下面的代碼,設置baseUrl參數為空,但是圖片給出了絕對網絡地址,所以我們可以正常加載到網絡圖片

 

        String htmlContent = "<h1>Android WebView測試</h1>\n" +
                "<p>下面顯示圖片</p>\n" +
                "<img src=\"https://wow.nosdn.127.net/1/wow/wowclassic/JVIX5HPT66L41555957772316.png\" alt=\"圖片加載失敗\" width=\"100%\">";
        mWebView.loadDataWithBaseURL("", htmlContent, "text/html", "utf-8",null);

 

下面的代碼,是baseUrl參數也是為空,但是圖片給出了絕對本地路徑,也可以正常的加載到保存在assets文件夾里的圖片

        String htmlContent = "<h1>Android WebView測試</h1>\n" +
                "<p>下面顯示圖片</p>\n" +
                "<img src=\"file:///android_asset/testImage.png\" alt=\"圖片加載失敗\" width=\"100%\">";
        mWebView.loadDataWithBaseURL("about:blank", htmlContent, "text/html", "utf-8",null);
        //也可以將空白參數寫成 about:blank 其實是一個意思...

baseUrl參數設置為相對地址或者路徑

下面的代碼,設置baseUrl參數為相對網絡地址

        String htmlContent = "<h1>Android WebView測試</h1>\n" +
                "<p>下面顯示圖片</p>\n" +
                "<img src=\"JVIX5HPT66L41555957772316.png\" alt=\"圖片加載失敗\" width=\"100%\">";
        mWebView.loadDataWithBaseURL("https://wow.nosdn.127.net/1/wow/wowclassic/", htmlContent, "text/html", "utf-8", null);

 

注意! 這里有一個小坑 baseUrl的參數 https://wow.nosdn.127.net/1/wow/wowclassic/ 這個路徑后面一定是/ 斜杠結尾, 而html內容 src=\"JVIX5HPT66L41555957772316.png\" 前面不能用 / 斜杠開頭 , 否則就會加載失敗

下面的代碼,設置baseUrl參數為相對本地路徑

        String htmlContent = "<h1>Android WebView測試</h1>\n" +
                "<p>下面顯示圖片</p>\n" +
                "<img src=\"IMG_20190524_175239.jpg\" alt=\"圖片加載失敗\" width=\"100%\">";
        mWebView.loadDataWithBaseURL("file:///storage/emulated/0/DCIM/Camera/", htmlContent,"text/html", "utf-8", null);

設置是否支持JavaScript

 

mWebView.getSettings().setJavaScriptEnabled(false);

 

設置縮放

mWebView.getSettings().setSupportZoom(true);//設置是否支持縮放
mWebView.getSettings().setBuiltInZoomControls(true);//設置縮放工具

注意,配置setSupportZoom后還需要setBuiltInZoomControls 組合才能體驗到縮放效果.

設置初始縮放比例

public void setInitialScale(int scaleInPercent);

設置按比例縮放文字大小

mWebView.getSettings().setDefaultFontSize(60);//設值范圍 1-72

設置滾動條風格

mWebView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_INSET);

獲取當前頁面的URL

public String getUrl(); 

獲取當前頁面的原始URL

重定向后可能當前url不同, 就是http headers的Referer參數,loadUrl時為null

public String getOriginalUrl(); 

獲取當前頁面的標題

public String getTitle(); 

獲取當前頁面的favicon 網址圖標

public Bitmap getFavicon(); 

獲取當前頁面的加載進度

public int getProgress();

通知WebView內核網絡狀態

用於設置JS屬性`window.navigator.isOnline`和產生HTML5事件`online/offline`

public void setNetworkAvailable(boolean networkUp) 

JavaScript

// 注入Java對象,提供給JavaScript操作
public void addJavascriptInterface(Object object, String name);
// 移除已注入的Java對象,下次加載或刷新頁面時生效
public void removeJavascriptInterface(String name);

// 對傳入的JS表達式求值,通過resultCallback返回結果
// 此函數添加於API19,必須在UI線程中調用,回調也將在UI線程
public void evaluateJavascript(String script, ValueCallback<String> resultCallback)

導航(前進后退)

// 復制一份BackForwardList
public WebBackForwardList copyBackForwardList();
// 是否可后退
public boolean canGoBack();
// 是否可前進
public boolean canGoForward();
// 是否可前進/后退steps頁,大於0表示前進小於0表示后退
public boolean canGoBackOrForward(int steps);

// 后退一頁
public void goBack();
// 前進一頁
public void goForward();
// 前進/后退steps頁,大於0表示前進小於0表示后退
//以當前的index為起始點前進或者后退到歷史記錄中指定的steps
//如果steps為負數則為后退,正數則為前進
public void goBackOrForward(int steps);

// 清除當前webview訪問的歷史記錄
public void clearHistory();

Back鍵控制網頁后退

問題:在不做任何處理前提下 ,瀏覽網頁時點擊系統的“Back”鍵,整個 Browser 會調用 finish()而結束自身
目標:點擊返回后,是網頁回退而不是推出瀏覽器
解決方案:在當前Activity中處理並消費掉該 Back 事件

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if ((keyCode == KEYCODE_BACK) && mWebView.canGoBack()) { 
        mWebView.goBack();
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

網頁查找功能

// 設置網頁查找結果回調
public void setFindListener(FindListener listener);
// 異步執行查找網頁內包含的字符串並設置高亮,查找結果會回調.
public void findAllAsync (String find);
// 查找下一個匹配的字符串
public void findNext (boolean forward);
// 清除網頁查找的高亮匹配字符串
public void clearMatches();

截屏/翻頁/縮放

// 保存網頁(.html)到指定文件
public void saveWebArchive(String filename);
// 保存網頁(.html)到文件
public void saveWebArchive(String basename, boolean autoname, ValueCallback<String> callback);

// 上翻一頁,即向上滾動WebView高度的一半
public void pageUp(boolean top);
// 下翻一頁,即向下滾動WebView高度的一半
public void pageDown(boolean bottom);

// 縮放
public void zoomBy(float factor);
// 放大
public boolean zoomIn();
// 縮放
public boolean zoomOut();

WebView的狀態

//激活WebView為活躍狀態,能正常執行網頁的響應
webView.onResume() ;

//當頁面被失去焦點被切換到后台不可見狀態,需要執行onPause
//通過onPause動作通知內核暫停所有的動作,比如DOM的解析、plugin的執行、JavaScript執行。
webView.onPause();

//當應用程序(存在webview)被切換到后台時,這個方法不僅僅針對當前的webview而是全局的全應用程序的webview
//它會暫停所有webview的layout,parsing,javascripttimer。降低CPU功耗。
webView.pauseTimers()
//恢復pauseTimers狀態
webView.resumeTimers();

//銷毀Webview
//在關閉了Activity時,如果Webview的音樂或視頻,還在播放。就必須銷毀Webview
//但是注意:webview調用destory時,webview仍綁定在Activity上
//這是由於自定義webview構建時傳入了該Activity的context對象
//因此需要先從父容器中移除webview,然后再銷毀webview:
rootLayout.removeView(webView); 
webView.destroy();

清除緩存數據

//清除網頁訪問留下的緩存
//由於內核緩存是全局的因此這個方法不僅僅針對webview而是針對整個應用程序.
Webview.clearCache(true);

//清除當前webview訪問的歷史記錄
//只會webview訪問歷史記錄里的所有記錄除了當前訪問記錄
Webview.clearHistory();

//這個api僅僅清除自動完成填充的表單數據,並不會清除WebView存儲到本地的數據
Webview.clearFormData();

其它

// 清除SSL偏好
public void clearSslPreferences();

// 查詢文檔中是否有圖片,查詢結果將被發送到msg.getTarget()
// 如果包含圖片,msg.arg1 為1,否則為0
public void documentHasImages(Message msg);

// 請求最近輕叩(tapped)的 錨點/圖像 元素的URL,查詢結果將被發送到msg.getTarget()
// msg.getData()中的url是錨點的href屬性,title是錨點的文本,src是圖像的src
public void requestFocusNodeHref(Message msg);

// 請求最近觸摸(touched)的 圖像元素的URL,查詢結果將被發送到msg.getTarget()
// msg.getData()中的url是圖像鏈接 
public void requestImageRef(Message msg) 


// 清除證書請求偏好,添加於API21
// 在WebView收到`android.security.STORAGE_CHANGED` Intent時會自動清除
public static void clearClientCertPreferences(Runnable onCleared)

// 開啟網頁內容(js,css,html...)調試模式,添加於API19
public static void setWebContentsDebuggingEnabled(boolean enabled)

####WebSettings類
生成一個WebView組件(有兩種方式)

//方式1:直接在在Activity中生成 
WebView webView = new WebView(this)

//方法2:在Activity的layout文件里添加webview控件:
WebView webview = (WebView) findViewById(R.id.webView1);
####配置-利用WebSettings子類
>//聲明WebSettings子類
WebSettings webSettings = webView.getSettings();

//如果訪問的頁面中要與Javascript交互,則webview必須設置支持Javascript
webSettings.setJavaScriptEnabled(true);  

//支持插件
webSettings.setPluginsEnabled(true); 

//設置自適應屏幕,兩者合用
webSettings.setUseWideViewPort(true); //將圖片調整到適合webview的大小 
webSettings.setLoadWithOverviewMode(true); // 縮放至屏幕的大小

//縮放操作
webSettings.setSupportZoom(true); //支持縮放,默認為true。是下面那個的前提。
webSettings.setBuiltInZoomControls(true); //設置內置的縮放控件。若為false,則該WebView不可縮放
webSettings.setDisplayZoomControls(false); //隱藏原生的縮放控件

//其他細節操作
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //關閉webview中緩存 
webSettings.setAllowFileAccess(true); //設置可以訪問文件 
webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通過JS打開新窗口 
webSettings.setLoadsImagesAutomatically(true); //支持自動加載圖片
webSettings.setDefaultTextEncodingName("utf-8");//設置編碼格式

// 存儲(storage)
// 啟用HTML5 DOM storage API,默認值 false
settings.setDomStorageEnabled(true); 
// 啟用Web SQL Database API,這個設置會影響同一進程內的所有WebView,默認值 false
// 此API已不推薦使用,參考:https://www.w3.org/TR/webdatabase/
settings.setDatabaseEnabled(true);  
// 啟用Application Caches API,必需設置有效的緩存路徑才能生效,默認值 false
// 此API已廢棄,參考:https://developer.mozilla.org/zh-CN/docs/Web/HTML/Using_the_application_cache
settings.setAppCacheEnabled(true); 
settings.setAppCachePath(context.getCacheDir().getAbsolutePath());

// 定位(location)
settings.setGeolocationEnabled(true);

/ 是否保存表單數據
settings.setSaveFormData(true);
// 是否當webview調用requestFocus時為頁面的某個元素設置焦點,默認值 true
settings.setNeedInitialFocus(true);  

// 是否支持viewport屬性,默認值 false
// 頁面通過`<meta name="viewport" ... />`自適應手機屏幕
settings.setUseWideViewPort(true);
// 是否使用overview mode加載頁面,默認值 false
// 當頁面寬度大於WebView寬度時,縮小使頁面寬度等於WebView寬度
settings.setLoadWithOverviewMode(true);
// 布局算法
settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);

// 是否支持Javascript,默認值false
settings.setJavaScriptEnabled(true); 
// 是否支持多窗口,默認值false
settings.setSupportMultipleWindows(false);
// 是否可用Javascript(window.open)打開窗口,默認值 false
settings.setJavaScriptCanOpenWindowsAutomatically(false);

// 資源訪問
settings.setAllowContentAccess(true); // 是否可訪問Content Provider的資源,默認值 true
settings.setAllowFileAccess(true);    // 是否可訪問本地文件,默認值 true
// 是否允許通過file url加載的Javascript讀取本地文件,默認值 false
settings.setAllowFileAccessFromFileURLs(false);  
// 是否允許通過file url加載的Javascript讀取全部資源(包括文件,http,https),默認值 false
settings.setAllowUniversalAccessFromFileURLs(false);

// 資源加載
settings.setLoadsImagesAutomatically(true); // 是否自動加載圖片
settings.setBlockNetworkImage(false);       // 禁止加載網絡圖片
settings.setBlockNetworkLoads(false);       // 禁止加載所有網絡資源

// 縮放(zoom)
settings.setSupportZoom(true);          // 是否支持縮放
settings.setBuiltInZoomControls(false); // 是否使用內置縮放機制
settings.setDisplayZoomControls(true);  // 是否顯示內置縮放控件

// 默認文本編碼,默認值 "UTF-8"
settings.setDefaultTextEncodingName("UTF-8");
settings.setDefaultFontSize(16);        // 默認文字尺寸,默認值16,取值范圍1-72
settings.setDefaultFixedFontSize(16);   // 默認等寬字體尺寸,默認值16
settings.setMinimumFontSize(8);         // 最小文字尺寸,默認值 8
settings.setMinimumLogicalFontSize(8);  // 最小文字邏輯尺寸,默認值 8
settings.setTextZoom(100);              // 文字縮放百分比,默認值 100

// 字體
settings.setStandardFontFamily("sans-serif");   // 標准字體,默認值 "sans-serif"
settings.setSerifFontFamily("serif");           // 襯線字體,默認值 "serif"
settings.setSansSerifFontFamily("sans-serif");  // 無襯線字體,默認值 "sans-serif"
settings.setFixedFontFamily("monospace");       // 等寬字體,默認值 "monospace"
settings.setCursiveFontFamily("cursive");       // 手寫體(草書),默認值 "cursive"
settings.setFantasyFontFamily("fantasy");       // 幻想體,默認值 "fantasy"


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    // 用戶是否需要通過手勢播放媒體(不會自動播放),默認值 true
    settings.setMediaPlaybackRequiresUserGesture(true);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // 5.0以上允許加載http和https混合的頁面(5.0以下默認允許,5.0+默認禁止)
    settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    // 是否在離開屏幕時光柵化(會增加內存消耗),默認值 false
    settings.setOffscreenPreRaster(false);
}

if (isNetworkConnected(context)) {
    // 根據cache-control決定是否從網絡上取數據
    settings.setCacheMode(WebSettings.LOAD_DEFAULT);
} else {
    // 沒網,離線加載,優先加載緩存(即使已經過期)
    settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
}

// deprecated
settings.setRenderPriority(WebSettings.RenderPriority.HIGH);
settings.setDatabasePath(context.getDir("database", Context.MODE_PRIVATE).getPath());
settings.setGeolocationDatabasePath(context.getFilesDir().getPath());

設置WebView緩存

當加載 html 頁面時,WebView會在/data/data/包名目錄下生成 database 與 cache 兩個文件夾
請求的 URL記錄保存在 WebViewCache.db,而 URL的內容是保存在 WebViewCache 文件夾下
是否啟用緩存:
優先使用緩存:

    WebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); 
      緩存模式如下:
       // LOAD_CACHE_ONLY: 不使用網絡,只讀取本地緩存數據 // LOAD_DEFAULT: (默認)根據cache-control決定是否從網絡上取數據。 // LOAD_NO_CACHE: 不使用緩存,只從網絡獲取數據. // LOAD_CACHE_ELSE_NETWORK,只要本地有,無論是否過期,或者no-cache,都使用緩存中的數據。 

//不使用緩存:

    WebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);

結合使用(離線加載)

if (NetStatusUtil.isConnected(getApplicationContext())) {
    webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);//根據cache-control決定是否從網絡上取數據。
} else {
    webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);//沒網,則從本地獲取,即離線加載
}
webSettings.setDomStorageEnabled(true); // 開啟 DOM storage API 功能
webSettings.setDatabaseEnabled(true);   //開啟 database storage API 功能
webSettings.setAppCacheEnabled(true);//開啟 Application Caches 功能
String cacheDirPath = getFilesDir().getAbsolutePath() + APP_CACAHE_DIRNAME;
webSettings.setAppCachePath(cacheDirPath); //設置  Application Caches 緩存目錄

//注意: 每個 Application 只調用一次 WebSettings.setAppCachePath(),WebSettings.setAppCacheMaxSize()

WebViewClient類

作用:處理各種通知 & 請求事件

常見方法1:shouldOverrideUrlLoading()

作用:打開網頁時不調用系統瀏覽器, 而是在本WebView中顯示;在網頁上的所有加載都經過這個方法,這個函數我們可以做很多操作。

復寫shouldOverrideUrlLoading()方法,使得打開網頁時不調用系統瀏覽器, 而是在本WebView中顯示
    webView.setWebViewClient(new WebViewClient(){
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, String url) {
          view.loadUrl(url);
      return true;
      }
  });

 

常見方法2:onPageStarted()

作用:開始載入頁面調用的,我們可以設定一個loading的頁面,告訴用戶程序在等待網絡響應。

webView.setWebViewClient(new WebViewClient(){
      @Override
      public void  onPageStarted(WebView view, String url, Bitmap favicon) {
         //設定加載開始的操作
      }
  });

常見方法3:onPageFinished()

作用:在頁面加載結束時調用。我們可以關閉loading 條,切換程序動作。

webView.setWebViewClient(new WebViewClient(){
      @Override
      public void onPageFinished(WebView view, String url) {
         //設定加載結束的操作
      }
  });

常見方法4:onLoadResource()

作用:在加載頁面資源時會調用,每一個資源(比如圖片)的加載都會調用一次。

  webView.setWebViewClient(new WebViewClient(){
      @Override
      public boolean onLoadResource(WebView view, String url) {
         //設定加載資源的操作
      }});

常見方法5:onReceivedError()

作用:加載頁面的服務器出現錯誤時(如404)調用。
App里面使用webview控件的時候遇到了諸如404這類的錯誤的時候,若也顯示瀏覽器里面的那種錯誤提示頁面就顯得很丑陋了,那么這個時候我們的app就需要加載一個本地的錯誤提示頁面,即webview如何加載一個本地的頁面

//步驟1:寫一個html文件(error_handle.html),用於出錯時展示給用戶看的提示頁面
//步驟2:將該html文件放置到代碼根目錄的assets文件夾下

//步驟3:復寫WebViewClient的onRecievedError方法
//該方法傳回了錯誤碼,根據錯誤類型可以進行不同的錯誤分類處理
    webView.setWebViewClient(new WebViewClient(){
      @Override
      public void onReceivedError(WebView view, int errorCode, String description, String failingUrl){
switch(errorCode)
                {
                case HttpStatus.SC_NOT_FOUND:
                    view.loadUrl("file:///android_assets/error_handle.html");
                    break;
          }  }
        });

常見方法6:onReceivedSslError()

作用:處理https請求
webView默認是不處理https請求的,頁面顯示空白,需要進行如下設置:

webView.setWebViewClient(new WebViewClient() {    
        @Override    
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {    
            handler.proceed();    //表示等待證書響應
        // handler.cancel();      //表示掛起連接,為默認方式
        // handler.handleMessage(null);    //可做其他處理
        }    
    });  

WebChromeClient類

作用:輔助 WebView 處理 Javascript 的對話框,網站圖標,網站標題等等。
常見使用:

常見方法1: onProgressChanged()

作用:獲得網頁的加載進度並顯示

webview.setWebChromeClient(new WebChromeClient(){
      @Override
      public void onProgressChanged(WebView view, int newProgress) {
          if (newProgress < 100) {
              String progress = newProgress + "%";
              progress.setText(progress);
            } else {
        }
    });

常見方法2: onReceivedTitle()

作用:獲取Web頁中的標題
每個網頁的頁面都有一個標題,比如www.baidu.com這個頁面的標題即“百度一下,你就知道”,那么如何知道當前webview正在加載的頁面的title並進行設置呢?

webview.setWebChromeClient(new WebChromeClient(){
    @Override
    public void onReceivedTitle(WebView view, String title) {
       titleview.setText(title);
    }

 


回調順序
shouldOverrideUrlLoading
onProgressChanged[10]
shouldInterceptRequest 
onProgressChanged[...]
onPageStarted
onProgressChanged[...]
onLoadResource 
onProgressChanged[...]
onReceivedTitle/onPageCommitVisible 
onProgressChanged[100]
onPageFinished
onReceivedIcon

資源加載回調:

shouldInterceptRequest() -> onLoadResource()

發生重定向時回調:
onPageStarted() -> shouldOverrideUrlLoading()

直接loadUrl的回調:
// 無重定向
onPageStarted() -> onPageFinished()
// 有重定向,shouldOverrideUrlLoading 返回 true 時 onPageFinished 仍會執行
onPageStarted() -> redirection -> ... -> onPageFinished()

用戶點擊鏈接的回調:
// shouldOverrideUrlLoading 返回 true 時不執行onPageStarted/onPageFinished
shouldOverrideUrlLoading() -> ...
// 無重定向
shouldOverrideUrlLoading() -> onPageStarted() -> onPageFinished()
// 有重定向
shouldOverrideUrlLoading() -> onPageStarted() -> redirection -> ... -> onPageFinished()

后退/前進/刷新時回調:
>onPageStarted() -> onPageFinished()

 

內存泄漏

直接 new WebView 並傳入 application context 代替在 XML 里面聲明以防止 activity 引用被濫用,能解決90+%的 WebView 內存泄漏。

vWeb =  new WebView(getContext().getApplicationContext());
container.addView(vWeb);

銷毀 WebView

if (vWeb != null) {
    vWeb.setWebViewClient(null);
    vWeb.setWebChromeClient(null);
    vWeb.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
    vWeb.clearHistory();

    ((ViewGroup) vWeb.getParent()).removeView(vWeb);
    vWeb.destroy();
    vWeb = null;
}

 

 在Android代碼里調用JavaScript方法

 方式一

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
    <p id="text">Android調用JavaScript測試</p>
</body>
<script>
    function demo(){
        alert("Android調用了JS的callJS方法");
    }
</script>
</html>

Android代碼部分:

             mWebView.evaluateJavascript("javascript:demo()", new ValueCallback<String>() {
                    @Override
                    public void onReceiveValue(String value) {
                        Log.e(TAG, "onReceiveValue: value="+value);

                    }
                });

 

 

 

 

 

 

 

 

end

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM