WebView 使用

1 篇文章 / 0 new
author
WebView 使用
► 載入URL
方式1. 載入一個網頁:
webView.loadUrl("http://www.google.com/")
方式2:載入apk包中的html頁面
webView.loadUrl("file:///android_asset/test.html")
方式3:載入手機本地的html頁面
webView.loadUrl("content://com.android.htmlfileprovider/sdcard/test.html")
方式4: 載入 HTML 頁面的一小段內容
webView.loadData(String data, String mimeType, String encoding)
參數說明:
參數1:內容,內容裡不能出現 ’#’, ‘%’, ‘\’ , ‘?’ 字元,若出現了需用 %23, %25, %27, %3f 對應來替代,否則會出現異常
參數2:內容的類型
參數3:文字編碼
[/java]

►運行狀態
啟動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.canGoBack()
後退網頁
webview.goBack()
是否可以前進                   
webview.canGoForward()
前進網頁
webview.goForward()
以當前的index為起始點前進或者後退到歷史記錄中指定的steps,如果steps為負數則為後退,正數則為前進
webview.goBackOrForward(int steps)
常見用法: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);
}
►清除暫存
清除網頁訪問留下的緩存, 由於內核緩存是全域的因此這個方法不僅僅針對webview而是針對整個應用程式.
webview.clearCache(true)
清除當前webview訪問的歷史記錄, 只會webview訪問歷史記錄裡的所有記錄除了當前訪問記錄
webview.clearHistory()
這個api僅僅清除自動完成填充的表單數據,並不會清除WebView存儲到本地的資料
webview.clearFormData()

►配置和管理
添加訪問網路許可權(AndroidManifest.xml)
<uses-permission android:name="android.permission.INTERNET"/>

聲明WebSettings子類
WebSettings webSettings = webView.getSettings()
 
如果訪問的頁面中要與Javascript交互,則webview必須設置支持Javascript
webSettings.setJavaScriptEnabled(true)
若載入的 html 裡有JS 在執行動畫等操作,會造成資源浪費(CPU、電量),在 onStop 和 onResume 裡分別把 setJavaScriptEnabled() 給設置成 false 和 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");//設置編碼格式

常見用法:設置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,都使用緩存中的資料。
 
結合使用(離線載入)
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類
作用:處理各種通知 & 請求事件
常見方法:
shouldOverrideUrlLoading()
作用:打開網頁時不調用系統流覽器, 而是在本WebView中顯示;在網頁上的所有載入都經過這個方法,這個函數我們可以做很多操作。
Webview webview = (WebView) findViewById(R.id.webView1);
webView.loadUrl("http://www.google.com/");
//webView.loadUrl("file:///android_asset/test.html");
//webView.loadUrl("content://com.android.htmlfileprovider/sdcard/test.html");
//複寫shouldOverrideUrlLoading()方法,使得打開網頁時不調用系統流覽器, 而是在本WebView中顯示
webView.setWebViewClient(new WebViewClient(){
@Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        view.loadUrl(url);
        return true;
    }
});
onPageStarted()
作用:開始載入頁面調用的,我們可以設定一個loading的頁面,告訴使用者程式在等待網路回應。

onPageFinished()
作用:在頁面載入結束時調用。我們可以關閉loading 條,切換程式動作。

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

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;
        }
    }
});
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 的對話方塊,網站圖示,網站標題等等。
常見使用:
onProgressChanged()
作用:獲得網頁的載入進度並顯示
webview.setWebChromeClient(new WebChromeClient(){
    @Override
    public void onProgressChanged(WebView view, int newProgress) {
        if (newProgress < 100) {
            String progress = newProgress + "%";
            progress.setText(progress);
        } else { }
});
onReceivedTitle()
作用:獲取Web頁中的標題
每個網頁的頁面都有一個標題,如何知道當前webview正在載入的頁面的title並進行設置呢?
webview.setWebChromeClient(new WebChromeClient(){
    @Override
    public void onReceivedTitle(WebView view, String title) {
        titleview.setText(title)}
onJsAlert()
作用:支持javascript的警告框
一般情況下在 Android 中為 Toast,在文本裡面加入\n就可以換行
webview.setWebChromeClient(new WebChromeClient() {
    @Override
    public boolean onJsAlert(WebView view, String url, String message, final JsResult result){
        new AlertDialog.Builder(MainActivity.this)
        .setTitle("JsAlert")
        .setMessage(message)
        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                result.confirm();
        }
    })
    .setCancelable(false)
    .show();
    return true;
}
onJsConfirm()
作用:支持javascript的確認框
webview.setWebChromeClient(new WebChromeClient() {
    @Override
    public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
        new AlertDialog.Builder(MainActivity.this)
        .setTitle("JsConfirm")
        .setMessage(message)
        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                result.confirm();
        }
    })
    .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            result.cancel();
        }
    })
    .setCancelable(false)
    .show();
    // 返回布林值:判斷點擊時確認還是取消
    // true表示點擊了確認;false表示點擊了取消;
    return true;
}
onJsPrompt()
作用:支援javascript輸入框
點擊確認返回輸入框中的值,點擊取消返回 null。
webview.setWebChromeClient(new WebChromeClient() {
    @Override
    public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) {
        final EditText et = new EditText(MainActivity.this);
        et.setText(defaultValue);
        new AlertDialog.Builder(MainActivity.this)
        .setTitle(message)
        .setView(et)
        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                result.confirm(et.getText().toString());
            }
        })
        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                result.cancel();
        }
    })
    .setCancelable(false)
    .show();
    return true;
}
►注意事項:如何避免WebView記憶體洩漏?
不在xml中定義 Webview ,而是在需要的時候在Activity中創建,並且Context使用 getApplicationgContext()
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
mWebView = new WebView(getApplicationContext());
mWebView.setLayoutParams(params);
mLayout.addView(mWebView);
在 Activity 銷毀(WebView)的時候,讓 WebView 載入null內容,然後移除 WebView,再銷毀 WebView,最後置空
@Override
protected void onDestroy() {
    if (mWebView != null) {
        mWebView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
        mWebView.clearHistory();
        ((ViewGroup) mWebView.getParent()).removeView(mWebView);
        mWebView.destroy();
        mWebView = null;
    }
    super.onDestroy();
}

from http://www.jianshu.com/p/3c94ae673e2a
Free Web Hosting