1. 程式人生 > >Android WebView使用,Http/Https,硬體加速等相關細節詳解

Android WebView使用,Http/Https,硬體加速等相關細節詳解

概述

在應用的開發過程中,經常遇到需要經常變化的頁面,一般針對這種頁面,我們會用WebView來實現.如隱私條款等等.並且隨著 hybrid 的興起,webview 將會更加常用.

loadDataWithBaseURL 與 loadData

loadData

//方法原型
loadData(String data, String mimeType, String encoding)

loadData 用於載入一段html文字,這個和loadUrl是有區別的,
loadUrl 是根據一個url來載入一個網頁,他們各有利弊,
參考:WebView到底該使用loadUrl還是loadData

其中loadData 使用 #、%、\、? 四種字元易出現問題.

% 會報找不到頁面錯誤,頁面全是亂碼。亂碼樣式見符件。
# 會讓你的goBack失效,但canGoBack是可以使用的。於是就會產生返回按鈕生效,但不能返回的情況。
\ 會被當做轉義字元.

如果出現亂碼問題,需要將encoding引數設定為utf-8.
mimeType,指定mineType型別,如text/html; charset=utf-8

loadDataWithBaseURL

//方法原型
 public void loadDataWithBaseURL(String baseUrl, String data,
            String mimeType, String encoding, String failUrl) {
    }
public
void loadData(String data, String mimeType, String encoding) { } public void loadUrl(String url) { } public void loadUrl(String url,Map<Stirng,String> extraHeaders) { }

loadDataWithBaseURL可以指定相對根路徑,也可以指定歷史Url

baseUrl相對根路徑,常見於WebView中的超連結或者是image元素,如使用絕對路徑傳""即可。

比如, 我們的data

格式:

String body ="示例:這裡有個img標籤,地址是相對路徑<img src='/uploads/allimg/130923/1FP02V7-0.png' />";

如果baseUrl沒有指定為網站域名,那麼這張圖片將顯示不出來。

常用屬性

通過mWebView.getSettings()拿到WebView的設定.

mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);//支援通過JS開啟新視窗
mWebView.getSettings().setSupportZoom(true);//設定是否支援縮放
mWebView.getSettings().setBuiltInZoomControls(true);//設定是否顯示縮放工具
webview.getSettings().setDisplayZoomControls(false);//設定縮放控制元件隱藏
/**http://stackoverflow.com/questions/5448841/what-do-setusewideviewport-and-setloadwithoverviewmode-precisely-do*/
webview.getSettings().setLoadWithOverviewMode(true);// loads the WebView completely zoomed out
webview.getSettings().setUseWideViewPort(true); //makes the Webview have a normal viewport (such as a normal desktop browser), while when false the webview will have a viewport constrained to its own dimensions (so if the webview is 50px*50px the viewport will be the same size)
webview.getSettings().setAllowFileAccess(true); // 允許訪問檔案  


mWebView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);//一般很少會用到這個,用WebView元件顯示普通網頁時一般會出現橫向滾動條,這樣會導致頁面檢視起來非常不方便。//LayoutAlgorithm是一個列舉,用來控制html的佈局,總共有三種類型://NORMAL:正常顯示,沒有渲染變化。//SINGLE_COLUMN:把所有內容放到WebView元件等寬的一列中。//NARROW_COLUMNS:可能的話,使所有列的寬度不超過螢幕寬度。
mWebView.getSettings().setDefaultFontSize(18);//設定預設的字型大小,預設為16,有效值區間在1-72之間。
//若要考慮相容3.0以下版本則:
/**http://jingyan.baidu.com/article/48b37f8d0b918e1a646488ec.html*/
if(android.os.Build.VERSION.SDK_INT>=11){
    this.getSettings().setDisplayZoomControls(false);
}else{
    this.setZoomControlHide(this); 
}

//Android 3.0(11) 以下使用以下方法:
//利用java的反射機制
public void setZoomControlHide(View view) {
        try {  
            Class webview = Class.forName("android.webkit.WebView");  
            Method method = webview.getMethod("getZoomButtonsController");  
            zoomController = (ZoomButtonsController) method.invoke(this, null);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
}  

-WebView 連結在WebView內部開啟,而非呼叫系統瀏覽器的方法.

重寫shouldOverrideUrlLoading,並且return true;

WebViewClient與WebChromeClient

WebViewClient主要幫助WebView處理各種通知、請求事件的,比如:

onLoadResource
onPageStart
onPageFinish
onReceiveError //錯誤,可以在此顯示一個錯誤頁面
onReceivedHttpAuthRequest

WebChromeClient主要輔助WebView處理Javascript的對話方塊、網站圖示、網站title、載入進度等,比如:

onCloseWindow//關閉WebView
onCreateWindow()
onJsAlert //WebView上alert無效,需要定製WebChromeClient處理彈出
onJsPrompt
onJsConfirm
onProgressChanged
onReceivedIcon
onReceivedTitle//獲取title

如果你的WebView只是用來處理一些v的頁面內容,只用WebViewClient就行了,如果需要更豐富的處理效果,比如JS、進度條等,就要用到WebChromeClient

比如,我們想要在webview 中相應Email,telIntent,我們繼承WebViewClient 並重寫shouldOverrideUrlLoading 方法

public abstract class WebClient extends android.webkit.WebViewClient {
  private final WeakReference<Context> contextWeakReference;

  public WebClient(Context context) {
    contextWeakReference = new WeakReference<>(context);
  }

  @Override public boolean shouldOverrideUrlLoading(WebView view, String url) {
    if (url.startsWith("mailto:") || url.startsWith("geo:") || url.startsWith("tel:")) {
      final Context context = contextWeakReference.get();
      if (context != null) {
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        context.startActivity(intent);
        view.reload();
      }
    } else {
      reloadUrl(view, url);
    }

    return true;
  }

  public abstract void reloadUrl(WebView view, String url);
}

onPageFinished:

onReceivedTitle()方法在goback()之後無效。

這時,我們可以使用onPageFinished(WebView view, String url)方法來實現返回及時重新整理標題

 WebView mWebView = (WebView) findViewById(R.id.mwebview);
    mWebView.setWebViewClient(new WebViewClient() { 
        @Override 
        public void onPageFinished(WebView view, String url) {
            setTitle(view.getTitle());
        } 
    }); 

處理https請求

android 預設是不處理https請求的,請求https會顯示空白。


webView.setWebViewClient(new WebViewClient() {  

        @Override  
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {  
            handler.proceed();  
            //default
//            handler.cancel();  
//            handler.handleMessage(null);  
        }  
    });  

cookies 和歷史紀錄

比如在某些場景中,我們的使用者在客戶端 登入了,要在 網頁中也保持登入狀態,則可以使用cookies 來實現,不過需要伺服器端配合完成.

//cookies清理
CookieSyncManager.createInstance(this); 
CookieSyncManager.getInstance().startSync(); 
CookieManager.getInstance().removeSessionCookie(); 

//清理cache 和歷史記錄
webView.clearCache(true); 
webView.clearHistory();

檔案下載

我們都知道WebView中 有這麼一個方法

// 方法原型
public void setDownloadListener(DownloadListener listener){}

那麼我們只需要自定義一個DownloadListener 即可

public class WebViewDownLoadListener implements DownloadListener {
  @Override public void onDownloadStart(String url, String userAgent, String contentDisposition,
      String mimetype, long contentLength) {
      // 引數含義: url :檔案現在連結
      // userAgent : 使用者瀏覽器代理
      // contentDisposition : 檔案描述符
      // mimetype : 檔案的型別
      // contentLength : 檔案的長度
  }
}

硬體加速

Android自帶的WebView非常的雞肋,比如不能開啟pdf,播放視屏也只能開啟硬體加速才能支援,但是這裡也存在著 問題,比如,在某些機型上會崩潰

這裡的做法是在 onPageStart中關閉硬體加速,在onPageFinish中開啟硬體加速

HTTP/HTTPS混合

在應用全面適配https後發現 某些圖片不再顯示了,通過抓包工具發現,是 Https 頁面中包含了 Http的 圖片連結。使用混合模式即可。

//http,https 混合使用
    // http://developer.android.com/reference/android/webkit/WebSettings.html#setMixedContentMode(int)
    if (Build.VERSION.SDK_INT >= 21) {
      webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
    }