Android中的WebView詳解

WebView詳解

基本用法

  • 清單文件配置WebView

        <WebView
          android:id="@+id/wv_news_detail"
          android:layout_width="match_parent"
          android:layout_height="match_parent" />
    
  • WebView加載網頁

      //加載網頁鏈接
      mWebView.loadUrl("http://www.itheima.com");
      //加載本地assets目錄下的網頁
      mWebView.loadUrl("file:///android_asset/demo.html");
    
  • WebView基本設置

      WebSettings settings = mWebView.getSettings();
      settings.setBuiltInZoomControls(true);// 顯示縮放按鈕(wap網頁不支持)
      settings.setUseWideViewPort(true);// 支持雙擊縮放(wap網頁不支持)
      settings.setJavaScriptEnabled(true);// 支持js功能
    
  • 設置WebViewClient

      mWebView.setWebViewClient(new WebViewClient() {
          // 開始加載網頁
          @Override
          public void onPageStarted(WebView view, String url, Bitmap favicon) {
              super.onPageStarted(view, url, favicon);
              System.out.println("開始加載網頁了");
          }
    
          // 網頁加載結束
          @Override
          public void onPageFinished(WebView view, String url) {
              super.onPageFinished(view, url);
              System.out.println("網頁加載結束");
          }
    
          // 所有鏈接跳轉會走此方法
          @Override
          public boolean shouldOverrideUrlLoading(WebView view, String url) {
              System.out.println("跳轉鏈接:" + url);
              view.loadUrl(url);// 在跳轉鏈接時強制在當前webview中加載
    
              //此方法還有其他應用場景, 比如寫一個超鏈接<a href="tel:110">聯系我們</a>, 當點擊該超鏈接時,可以在此方法中獲取鏈接地址tel:110, 解析該地址,獲取電話號碼, 然后跳轉到本地打電話頁面, 而不是加載網頁, 從而實現了webView和本地代碼的交互
          
              return true;
          }
      });
    
  • 設置WebChromeClient

      mWebView.setWebChromeClient(new WebChromeClient() {
          @Override
          public void onProgressChanged(WebView view, int newProgress) {
              super.onProgressChanged(view, newProgress);
              // 進度發生變化
              System.out.println("進度:" + newProgress);
          }
    
          @Override
          public void onReceivedTitle(WebView view, String title) {
              super.onReceivedTitle(view, title);
              // 網頁標題
              System.out.println("網頁標題:" + title);
          }
      });
    
  • WebView加載上一頁和下一頁

      mWebView.goBack();//跳到上個頁面
      mWebView.goForward();//跳到下個頁面
      mWebView.canGoBack();//是否可以跳到上一頁(如果返回false,說明已經是第一頁)
      mWebView.canGoForward();//是否可以跳到下一頁(如果返回false,說明已經是最后一頁)
    

WebView高級用法

緩存

  • 緩存設置

      WebSettings settings = mWebView.getSettings();
    
      //只要本地有,無論是否過期,或者no-cache,都使用緩存中的數據
      settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
      //只加載緩存
      settings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);
      //根據cache-control決定是否從網絡上取數據
      settings.setCacheMode(WebSettings.LOAD_DEFAULT);
      //不加載緩存
      settings.setCacheMode(WebSettings.LOAD_NO_CACHE);    
    
      什么是cache-control?
      cache-control是在請求網頁時服務器的響應頭,此響應頭用于決定網頁的緩存策略.
      常見的取值有public(所有內容都將被緩存), private(內容只緩存到私有緩存中),no-cache(所有內容都不會被緩存),max-age=xxx(緩存的內容將在 xxx 秒后失效)等等
    

    如圖所示:

Cache_Control.png
  • 清理緩存

      最簡便的方式:
      mWebView.clearCache(true);
    
      另外一種方式:
      //刪除緩存文件夾
      File file = CacheManager.getCacheFileBaseDir(); 
    
         if (file != null && file.exists() && file.isDirectory()) { 
          for (File item : file.listFiles()) { 
           item.delete(); 
          } 
          file.delete(); 
         } 
      
      //刪除緩存數據庫
      context.deleteDatabase("webview.db"); 
      context.deleteDatabase("webviewCache.db");
    

Cookie

  • Cookie設置

      CookieSyncManager.createInstance(this);
      CookieManager cookieManager = CookieManager.getInstance();
      cookieManager.setAcceptCookie(true);
    
      String cookie = "name=xxx;age=18";
      cookieManager.setCookie(URL, cookie);
      CookieSyncManager.getInstance().sync();
    
  • 獲取Cookie

      CookieManager cookieManager = CookieManager.getInstance();
      String cookie = cookieManager.getCookie(URL);
    
  • 清除Cookie

      CookieSyncManager.createInstance(context);  
      CookieManager cookieManager = CookieManager.getInstance(); 
      cookieManager.removeAllCookie();
      CookieSyncManager.getInstance().sync();  
    

Android和Js交互##

如果Js和Android實現了交互, 那么我們就可以在網頁中隨意調用本地的Java代碼, 也就是實現了WebView和本地代碼的交互. 一旦WebView可以操作Android本地代碼, 那么WebView的功能就會更加強大,以后我們直接在一個WebView中就幾乎可以實現Android的所有功能,Android原生控件就沒有了用武之地.

  • Js調用Android

      WebSettings settings = mWebView.getSettings();
      settings.setJavaScriptEnabled(true);//開啟js
    
      mWebView.loadUrl("file:///android_asset/demo.html");//加載本地網頁
      mWebView.setWebChromeClient(new WebChromeClient());//此行代碼可以保證js的alert彈窗正常彈出
    
      //核心方法, 用于處理js被執行后的回調
      mWebView.addJavascriptInterface(new JsCallback() {
    
          @JavascriptInterface//注意:此處一定要加該注解,否則在4.1+系統上運行失敗
          @Override
          public void onJsCallback() {
              System.out.println("js調用Android啦");
          }
      }, "demo");//參1是回調接口的實現;參2是js回調對象的名稱
    
      //定義回調接口
      public interface JsCallback {
          public void onJsCallback();
      }
    
  • Android調用Js

      //直接使用webview加載js就可以了
      mWebView.loadUrl("javascript:wave()");
    
  • 附上demo.html源碼

      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      </head>
      <script language="javascript">
          /* This function is invoked by the activity */
          function wave() {
              alert("Android調用Js啦");
          }
      </script>
      <body>
          <!-- Js調用Android代碼 -->
          <a onClick="window.demo.onJsCallback()"><div style="width:80px;
              margin:0px auto;
              padding:10px;
              text-align:center;
              border:2px solid #202020;" >
                  <img id="droid" src="android_normal.png"/><br>
                  Click me!
          </div></a>
      </body>
    </html>
    

    注意: js回調的方法的書寫格式: onClick="window.demo.onJsCallback()
    格式是: window.js回調對象的名稱(要和java代碼中設置的一致).回調方法名稱(要和java代碼中設置的一致)

  • 注意事項

    Js調用Android的方式具有版本兼容問題. 經測試, 在2.2, 4.0+ 系統上運行穩定, 可以正常調用, 但是在2.3系統上運行時出現崩潰.原因是底層進行JNI調用時,把一個Java中的String對象當數組來訪問了,最終導致虛擬機崩潰. 基本算是一個比較嚴重的BUG,沒辦法解決,所以如果說用WebView組件想在js和java之間相互調用的話就沒辦法適應所有機型.

    參考鏈接:
    https://code.google.com/p/android/issues/detail?id=12987

    http://www.2cto.com/kf/201108/101375.html

目前一些比較前衛的app就只使用一個WebView作為整體框架,app中的所有內容全部使用html5進行展示.比如12306手機客戶端. 這樣做的好處就是可以實現跨平臺, 只需要一份h5代碼, 就可以在Android和Ios平臺上同時運行, 而且更新也更加簡便, 只需要更改服務器的h5頁面, 本地客戶端就馬上會同步更新,無需下載apk覆蓋安裝. 不過劣勢也很明顯, h5受網速限制,往往加載速度比較慢, 沒有原生控件流暢, 用戶體驗較差. 所以目前完全使用h5搭建app并沒有成為主流方式.

WebView的應用場景

WebView的應用場景我們無需多講, 此處我只提一點: 隨著html5的普及, 很多app都會內嵌webview來加載html5頁面, 而且h5做的和app原生控件極其相似, 那么我們如何辨認某個頁面使用h5做的還是用原生控件做的呢?

打開開發者選項, 你會看到這樣一個選項:顯示布局邊界

setting.png

勾選之后,所有原生控件布局的邊框都會顯示出來

bjbj.png

我們現在在這種狀態下打開一個WebView看一眼(這是微信錢包-滴滴出行的頁面)

ddcx.jpg

發現蛛絲馬跡了嗎? 如果是WebView的話, 只有在WebView邊緣才會顯示一個邊框, WebView內部是沒有邊框的;如果是原生控件,怎么可能邊框這么少呢? 從而我們可以斷定,微信的滴滴出行頁面一定是用WebView加載網頁實現的, 而不是系統原生控件.

WebView介紹到此結束, 感謝捧場!!!

附件下載地址: <a >http://pan.baidu.com/s/1mgrPlmK</a>

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,002評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,400評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,136評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,452評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,818評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,997評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,552評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,292評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,510評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,721評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,235評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,480評論 2 379

推薦閱讀更多精彩內容