WebView詳解【轉(zhuǎn)載】

基本用法

  • 清單文件配置WebView

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

      //加載網(wǎng)頁鏈接
      mWebView.loadUrl("https://www.google.com");
      //加載本地assets目錄下的網(wǎng)頁
      mWebView.loadUrl("file:///android_asset/demo.html");
    
  • WebView基本設(shè)置

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

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

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

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

WebView高級用法

緩存

  • 緩存設(shè)置

      WebSettings settings = mWebView.getSettings();
    
      //只要本地有耍铜,無論是否過期赦拘,或者no-cache唆缴,都使用緩存中的數(shù)據(jù)
      settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
      //只加載緩存
      settings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);
      //根據(jù)cache-control決定是否從網(wǎng)絡(luò)上取數(shù)據(jù)
      settings.setCacheMode(WebSettings.LOAD_DEFAULT);
      //不加載緩存
      settings.setCacheMode(WebSettings.LOAD_NO_CACHE);    
    
      什么是cache-control?
      cache-control是在請求網(wǎng)頁時服務(wù)器的響應頭,此響應頭用于決定網(wǎng)頁的緩存策略.
      常見的取值有public(所有內(nèi)容都將被緩存), private(內(nèi)容只緩存到私有緩存中),no-cache(所有內(nèi)容都不會被緩存),max-age=xxx(緩存的內(nèi)容將在 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(); 
         } 
      
      //刪除緩存數(shù)據(jù)庫
      context.deleteDatabase("webview.db"); 
      context.deleteDatabase("webviewCache.db");
    

Cookie

  • Cookie設(shè)置

      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實現(xiàn)了交互, 那么我們就可以在網(wǎng)頁中隨意調(diào)用本地的Java代碼, 也就是實現(xiàn)了WebView和本地代碼的交互. 一旦WebView可以操作Android本地代碼, 那么WebView的功能就會更加強大,以后我們直接在一個WebView中就幾乎可以實現(xiàn)Android的所有功能,Android原生控件就沒有了用武之地.

  • Js調(diào)用Android

      WebSettings settings = mWebView.getSettings();
      settings.setJavaScriptEnabled(true);//開啟js
    
      mWebView.loadUrl("file:///android_asset/demo.html");//加載本地網(wǎng)頁
      mWebView.setWebChromeClient(new WebChromeClient());//此行代碼可以保證js的alert彈窗正常彈出
    
      //核心方法, 用于處理js被執(zhí)行后的回調(diào)
      mWebView.addJavascriptInterface(new JsCallback() {
    
          @JavascriptInterface//注意:此處一定要加該注解,否則在4.1+系統(tǒng)上運行失敗
          @Override
          public void onJsCallback() {
              System.out.println("js調(diào)用Android啦");
          }
      }, "demo");//參1是回調(diào)接口的實現(xiàn);參2是js回調(diào)對象的名稱
    
      //定義回調(diào)接口
      public interface JsCallback {
          public void onJsCallback();
      }
    
  • Android調(diào)用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調(diào)用Js啦");
          }
      </script>
      <body>
          <!-- Js調(diào)用Android代碼 -->
          <a onClick="window.demo.onJsCallback()"><div style="width:80px;
              margin:0px auto;
              padding:10px;
              text-align:center;
              border:2px solid #202020;" >
                  ![](android_normal.png)<br>
                  Click me!
          </div></a>
      </body>
    

    </html>

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

  • 注意事項

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

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

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

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

WebView的應用場景

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

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

setting.png

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

bjbj.png

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

ddcx.jpg

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

WebView介紹到此結(jié)束, 感謝捧場!!!

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市搓茬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌么翰,老刑警劉巖青灼,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件暴心,死亡現(xiàn)場離奇詭異,居然都是意外死亡杂拨,警方通過查閱死者的電腦和手機专普,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來弹沽,“玉大人檀夹,你說我怎么就攤上這事〔唛伲” “怎么了炸渡?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長丽已。 經(jīng)常有香客問我蚌堵,道長,這世上最難降的妖魔是什么沛婴? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任吼畏,我火速辦了婚禮,結(jié)果婚禮上嘁灯,老公的妹妹穿的比我還像新娘宫仗。我一直安慰自己,他們只是感情好旁仿,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布藕夫。 她就那樣靜靜地躺著,像睡著了一般枯冈。 火紅的嫁衣襯著肌膚如雪毅贮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天尘奏,我揣著相機與錄音滩褥,去河邊找鬼。 笑死炫加,一個胖子當著我的面吹牛瑰煎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播俗孝,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼酒甸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了赋铝?” 一聲冷哼從身側(cè)響起插勤,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后农尖,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體析恋,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年盛卡,在試婚紗的時候發(fā)現(xiàn)自己被綠了助隧。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡滑沧,死狀恐怖并村,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嚎货,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布蔫浆,位于F島的核電站殖属,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏瓦盛。R本人自食惡果不足惜洗显,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望原环。 院中可真熱鬧挠唆,春花似錦、人聲如沸嘱吗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谒麦。三九已至俄讹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間绕德,已是汗流浹背患膛。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留耻蛇,地道東北人踪蹬。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像臣咖,于是被迫代替她去往敵國和親跃捣。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容