有關WebView的一些使用方法

有關WebView的一些使用方法

muyuren 2016-04-13javascript

Android系統中內置了一款高性能 webkit 內核瀏覽器,在 SDK 中封裝爲一個叫作 WebView 組件。html

在開發過程當中應該注意幾點:java

1.這是最基本的 AndroidManifest.xml 中必須添加訪問網絡權限。 android

2.若是訪問的頁面中有 Javascript,則 WebView 必須設置支持 Javascript。web

WebView.getSettings().setJavaScriptEnabled(true);

3.若是頁面中連接,若是但願點擊連接繼續在當前browser中響應,而不是新開Android的系統browser中響應該連接,必須覆蓋 WebView的WebViewClient對象。瀏覽器

mWebView.setWebViewClient(new WebViewClient(){
    public boolean shouldOverrideUrlLoading(WebView view, String url){ 
        view.loadUrl(url);
        return true;
    }
});

4.若是不作任何處理 ,瀏覽網頁,點擊系統「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);
}

 

與js互調服務器

既然能夠顯示網頁,那麼固然也可讓網頁操做本地方法。(因爲一行寫不下,縮進我調整了一下)cookie

public class WebViewDemo extends Activity { 
    private WebView mWebView;
    private Handler mHandler = new Handler(); 

    public void onCreate(Bundle icicle) { 

    setContentView(R.layout.WebViewdemo);
    mWebView = (WebView) findViewById(R.id.WebView); 
    WebSettings webSettings = mWebView.getSettings(); 
    webSettings.setJavaScriptEnabled(true); 
    mWebView.addJavascriptInterface(new Object() {
      public void clickOnAndroid() {
          mHandler.post(new Runnable() {
              public void run() { 
                  mWebView.loadUrl("javascript:wave()");
              }
          });
      }
    }, "demo"); 
    mWebView.loadUrl("file:///android_asset/demo.html"); 

    }
}

咱們看 addJavascriptInterface(Object obj,String interfaceName)這個方法 ,該方法將一個java對象綁定到一個javascript對象中,javascript對象名就是 interfaceName(demo),做用域是Global.這樣初始化 WebView 後,在WebView加載的頁面中就能夠直接經過javascript:window.demo訪問到綁定的java對象了. 來看看在html中是怎樣調用的.網絡

<html>
<script language="javascript">
  function wave() {
    document.getElementById("droid").src="android_waving.png";
  }
</script>
<body>
  <a onClick="window.demo.clickOnAndroid()">
  <img id="droid" src="android_normal.png" mce_src="android_normal.png"/><br> Click me! </a>
</body>
</html>

這樣在 javascript 中就能夠調用 java 對象的 clickOnAndroid()方法了,一樣咱們能夠在此對象中定義不少方法(好比發短信,調用聯繫人列表等手機系統功能),這裏 wave()方法是 java 中調用 javascript 的例子.

須要說明一點:addJavascriptInterface方法中要綁定的Java對象及方法要運行另外的線程中,不能運行在構造他的線程中,這也是使用 Handler 的目的.

 

讓js調用Android代碼

首先簡述 WebView、WebViewClient、WebChromeClient 之間的區別: 

在 WebView 的設計中,不是什麼事都要 WebView類乾的,有些瑣事是分給其餘人的,這樣 WebView 專心幹好 本身的解析、渲染工做就好了.WebViewClient 就是幫助 WebView 處理各類通知、請求事件等 ,WebChromeClient 是輔助 WebView 處理 Javascript 的對話框,網站圖標,網站 title.

 

功能實現:

利用 android 中的 WebView 加載一個 html 網頁,在 html 網頁中定義一個按鈕,點擊按鈕彈出一 個 toast.

實現步驟:

首先定義一個接口類,將上下文對象傳進去,在接口類中定義要在 js 中實現的方法。 

接着在assets資源包下定義一個 html 文件,在文件中定義一個 button.button 的點擊事件定義爲一個 js 函數.

以後在 xml 中定義一個 WebView 組件,在活動類中獲取 WebView 並對 WebView 參數進行設置,此處特別注意要設置 WebView 支持 js 且將定義的 js 接口類添加到 WebView 中去,此後在 js 中就能夠利用該接口類中定義的 函數了.即:

myWebView.getSettings().setJavaScriptEnabled(true);

myWebView.addJavascriptInterface(new JavaScriptinterface(this),」android」);

最後利用 WebView 加載本地 html 文件的方法是:

myWebView.loadData(htmlText,"text/html", "utf-8");

此處的htmltext 是以字符串的方式讀取 assets 報下 html中的內容.

 

實現利用返回鍵返回到上一頁:

設置 WebView 的按鍵監聽,監聽到期返回鍵並判斷網頁是否可以返回 ,利用 WebView 的 goBack()返回到上一頁.

 

WebView 緩存

在項目中若是使用到 WebView 控件,當加載 html 頁面時,會在/data/data/包名目錄下生成 database 與 cache 兩個文件夾。

請求的 url 記錄是保存在 WebViewCache.db,而 url 的內容是保存在 WebViewCache 文件夾下. 你們能夠本身動手試一下,定義一個html文件,在裏面顯示一張圖片,用WebView加載出來,而後再試着從緩存裏把這張圖片讀取出來並顯示 。

 

WebView 刪除緩存

其實已經知道緩存保存的位置了,那麼刪除就很簡單了,獲取到這個緩存,而後刪掉他就行了。

//刪除保存於手機上的緩存
private int clearCacheFolder(File dir,long numDays) { 
  int deletedFiles = 0;
  if (dir!= null && dir.isDirectory()){
    try {
      for (File child:dir.listFiles()){
          if (child.isDirectory()) {
            deletedFiles += clearCacheFolder(child, numDays);
        }
        if (child.lastModified() < numDays) {
          if (child.delete()) {
           deletedFiles++; 
          }
        }
      }
    } catch(Exception e) {
      e.printStackTrace(); 
    }
  }
  return deletedFiles; 
}

是否啓用緩存功能也是能夠控制的

//優先使用緩存: 
    WebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); 
    //不使用緩存: 
    WebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);

在退出應用的時候加上以下代碼,能夠完整的清空緩存

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");

 

WebView 處理 404 錯誤

顯示網頁還會遇到一個問題,就是網頁有可能會找不到,WebView固然也是能夠處理的

public class WebView_404 extends Activity { 
    private Handler handler = new Handler() {
    public void handleMessage(Message msg) {
      if(msg.what==404) {//主頁不存在
        //載入本地 assets 文件夾下面的錯誤提示頁面 404.html 
        web.loadUrl("file:///android_asset/404.html");
      }else{
        web.loadUrl(HOMEPAGE);
      }
    }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
      web.setWebViewClient(new WebViewClient() {
    public boolean shouldOverrideUrl(WebView view,String url) { 
        if(url.startsWith("http://") && getRespStatus(url)==404) {
          view.stopLoading();
          //載入本地 assets 文件夾下面的錯誤提示頁面 404.html 
          view.loadUrl("file:///android_asset/404.html");
        }else{
          view.loadUrl(url);
        }
          return true;
        }
      });
      new Thread(new Runnable() {
    public void run() {
          Message msg = new Message();
          //此處判斷主頁是否存在,由於主頁是經過 loadUrl 加載的,
          //此時不會執行 shouldOverrideUrlLoading 進行頁面是否存在的判斷 //進入主頁後,點主頁裏面的連接,連接到其餘頁面就必定會執行
          shouldOverrideUrlLoading 方法了 
          if(getRespStatus(HOMEPAGE)==404) {
          msg.what = 404;
          }
          handler.sendMessage(msg);
      }).start();
  }
}

 

 

判斷 WebView 是否已經滾動到頁面底端

在View中有一個getScrollY()方法,能夠返回當前可見區域的頂端距整個頁面頂端的距離,也就是當前內容滾動的距離。

還有getHeight()或者 getBottom()方法都返回當前 View 這個容器的高度 

在ViewView中還有getContentHeight() 方法能夠返回整個 html 頁面的高度,但並不等同於當前整個頁面的高度 ,由於 WebView 有縮放功能。你能夠經過以下代碼來啓動或關閉webview的縮放功能。

mWebView.getSettings().setSupportZoom(true);
mWebView.getSettings().setBuiltInZoomControls(true);

因此當前整個頁面的高度實際上應該是原始 html 的高度再乘上縮放比例. 所以,更正後的結果 ,準確的判斷方法應該是:

// 若是已經處於底端
if(WebView.getContentHeight*WebView.getScale() -(webvi ew.getHeight()+WebView.getScrollY())){ 
  //XXX
}

 

WebView獲取服務器中的 session 問題

接下來咱們講以下兩個問題:

Android 中的 WebView 如何獲取服務器頁面的 jsessionid 的值

Android 的 WebView 又是如何把獲得的 jsessionid 的值在 set 到服務器中,一致達到他們在同一個 jsessionid 的回話中.

其實很是很是簡單,只不過是幾個方法罷了:

CookieManager cm = CookieManager.getInstance(); 
cm.removeAllCookie();
cm.getCookie(url);
cm.setCookie(url, cookie);

另外還有個 CookieSyncManager,也許你會在一些舊的項目中看到它。從名字來理解,它實際上應該是一個異步緩存器。不過咱們看到這個方法已經被標記爲過期了,查看源碼能夠看到過期緣由是如今WebView已是自動的異步緩存了,因此這個類已經沒有存在的意義了。 CookieSyncManager

 

WebView清除本地cookies

首先,要清除確定要會添加,這裏給你們提供一個工具方法:

/***
     * 若是用戶已經登陸,則同步本地的cookie到webview中
     */
    public void synCookies() {
        if (!CacheUtils.isLogin(this)) return;
        CookieSyncManager.createInstance(this);
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.setAcceptCookie(true);
        cookieManager.removeSessionCookie();//移除
        String cookies = PreferenceHelper.readString(this, AppConfig.COOKIE_KEY, AppConfig.COOKIE_KEY);
        KJLoger.debug(cookies);
        cookieManager.setCookie(url, cookies);
        CookieSyncManager.getInstance().sync();
    }

 

在使用網頁版淘寶或百度登陸時,WebView會自動登陸上次的賬號!(由於WebView 記錄了賬號和密碼的cookies) 因此,須要清除 SessionCookie也是有必要的。 

那麼CookieManager一樣也爲咱們提供了清除cookie的方法

CookieManager.getInstance().removeSessionCookie();

這裏順便說一下WebView自己也是會記錄html緩存的,webview自己就提供了清理緩存的方法,其中參數true是指是否包括磁盤文件也一併清除:

webview.clearCache(true);
webview.clearHistory();
相關文章
相關標籤/搜索