android webview 在專案中的那些坑
在專案開發過程中,webview常用於顯示網頁或h5頁面,這樣可以實時更新,遇到問題可以迅速修復。由於android碎片化嚴重,所以webview在每個版本都有修改,因此在開發過程中遇到過各種各樣的坑,現在總結一些曾經遇到的坑。
1,載入完成回撥不正確。
onPageStarted與onPageFinished次數不一致,如果你在start中進行進度條載入處理,finish中結束,會導致進度條一直不消失。因此可以在onProgressChanged進行處理。當newProgress為100時表示頁面載入完成。
2,檔案選擇函式修改。 // FILE UPLOAD <3.0 publicvoidopenFileChooser(ValueCallback<Uri> uploadFile) {
Android 5.0+ 重寫 onShowFileChooser 生效;
3,跨域cookie讀取
什麼是跨域,簡單的說就是不同的域名,我們都知道在pc上我們用瀏覽器訪問網址,不同的網址都會在本地儲存一些cookie資訊,這樣就可以實現比如自動登入等功能,在pc上不同域名是不能相互讀取其他域下的cookie資訊的(非web專業開發人員,如果理解有誤,歡迎指出)。
但是在Android上在api 23之前,是可以跨域讀取cookie的,比如A域寫入一個userId的cookie,B域可以讀取該值。但是在23時,系統將該值設定成了false,不再讓跨域讀取了。如果你的應用有跨域讀取需求,怎麼辦?可以採用如下方式進行開啟:
/**
* 設定跨域cookie讀取
*/
public final void setAcceptThirdPartyCookies() {
//target 23 default false, so manual set true
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
這裡我們來看看setAcceptThirdPartyCookies的註釋:
Sets whether the {@link WebView} should allow third party cookies to be set.
Allowing third party cookies is a per WebView policy and can be set
differently on different WebView instances.
Apps that target {@link android.os.Build.VERSION_CODES#KITKAT} or below
default to allowing third party cookies. Apps targeting
{@link android.os.Build.VERSION_CODES#LOLLIPOP} or later default to disallowing
third party cookies.
4,http/https混合載入
在現階段,很多網站都改成了https進行訪問,https可以提升訪問網站的安全性,防止資訊被竊取,如果所有的網頁都是https且網頁內的連結也是都是https,那就沒有混合載入(文字區域https,圖片檔案http載入)的問題了。但是很多資源現階段還沒有改變成https訪問,往往頁面都嵌入了http的連結。這種混合網頁如果不進行處理,直接載入是會出現錯誤的。怎麼解決這個問題?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
- 1
- 2
- 3
- 1
- 2
- 3
這也是一個分版本的函式,在api 23之前,預設是可以混合載入的,但是在23時,預設值改成了MIXED_CONTENT_NEVER_ALLOW,因此如果你有混合載入的需求,設定setMixedContentMode為MIXED_CONTENT_ALWAYS_ALLOW。
5,閃屏
WebView如果開啟了硬體加速,多次開啟,會導致介面花屏,或者介面繪製有殘留。這個在5.0剛出來的時候發生過多次,但是當時忘記截圖了。當時也沒有打算要把這些給記錄下來。這裡我已經復現不了了。如果你遇到了。關閉硬體加速就好了。關閉硬體加速這種情況會好很多,但無法獲得很好的瀏覽體驗,你會感覺網頁滑動的時候一卡一卡的,不跟手。
6,資源的及時釋放和耗電問題
當你的程式呼叫了WebView載入網頁,WebView會自己開啟一些執行緒(?),如果你沒有正確地將WebView銷燬的話,這些殘餘的執行緒(?)會一直在後臺執行,由此導致你的應用程式耗電量居高不下。必要時要手動釋放
@Override
protectedvoidonDestroy() {
super.onDestroy();
if (webView != null) {
root.removeView(webView);
webView.removeAllViews();
webView.destroy();
}
}
7,webview元件忽略SSL證書驗證錯誤漏洞
漏洞描述
Android WebView
元件載入網頁發生證書認證錯誤時,會呼叫WebViewClient
類的onReceivedSslError
方法[1],如果該方法實現呼叫了handler.proceed()
來忽略該證書錯誤,則會受到中間人攻擊的威脅,可能導致隱私洩露
測試方法
實現onReceivedSslError
的處理,漏洞程式碼樣例:
...
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new JsBridge(mContext), JS_OBJECT);
mWebView.loadUrl("http://www.example.org/tests/addjsif/");
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed(); // Ignore SSL certificate errors
}
});
...
如上程式碼在onReceivedSslError
處理時沒有進行cancel
,還是使用了proceed()
,忽略掉了發生的SSL異常。
解決方案
當發生證書認證錯誤時,採用預設的處理方法handler.cancel()
,停止載入問題頁面。當然,如果你的專案對安全性要求不高,對體驗要求高,可以用proceed()處理忽略。