Android學習之 WebView使用小結
網上關於HTML5規範定稿的一篇見解文章:
http://www.csdn.net/article/2014-11-06/2822513-how-html5-changes
本篇主要基於這段時間對WebView的使用經驗和網上學習到的對WebView開發做一個要點小結:
一、WebView基於webkit引擎展現web頁面的控制元件,使用前需要在Android Manifest file中配置internet訪問許可權,否則提示頁面無法訪問。
<manifest ... >
<uses-permission android:name="android.permission.INTERNET" />
...
</manifest>
1、設定WebSettings類
WebSettings用來對WebView的配置進行配置和管理,比如是否可以進行檔案操作、快取的設定、頁面是否支援放大和縮小、是否允許使用資料庫api、字型及文字編碼設定、是否允許js指令碼執行、是否允許圖片自動載入、是否允許資料及密碼儲存等等
示例程式碼如下:
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
webSettings.setDomStorageEnabled(true);
webSettings.setDatabaseEnabled(true);
webSettings.setAppCacheEnabled(true);
webSettings.setAllowFileAccess(true);
webSettings.setSavePassword(true);
webSettings.setSupportZoom(true);
webSettings.setBuiltInZoomControls(true);
/**
* 用WebView顯示圖片,可使用這個引數 設定網頁佈局型別:
* 1、LayoutAlgorithm.NARROW_COLUMNS :適應內容大小
* 2、LayoutAlgorithm.SINGLE_COLUMN : 適應螢幕,內容將自動縮放
*/
webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
webSettings.setUseWideViewPort(true);
mWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
mWebView.setHorizontalScrollbarOverlay(true);
mWebView.setHorizontalScrollBarEnabled(true);
mWebView.requestFocus();
2、設定WebChromeClient子類WebChromeClient會在一些影響瀏覽器ui互動動作發生時被呼叫,比如WebView關閉和隱藏、頁面載入進展、js確認框和警告框、js載入前、js操作超時、webView獲得焦點等等
mWebView.setWebChromeClient(new MyWebChromeClient());
3、設定WebViewClient子類WebViewClient會在一些影響內容渲染的動作發生時被呼叫,比如表單的錯誤提交需要重新提交、頁面開始載入及載入完成、資源載入中、接收到https認證需要處理、頁面鍵盤響應、頁面中的url開啟處理等等
mWebView.setWebViewClient(new MyWebViewClient());
4、設定addJavascriptInterface方法使Js呼叫Native本地Java物件,實現本地Java程式碼和HTML頁面進行互動,
注意:因為安全問題的考慮 Google在使用Android API 17以上的版本的時候 需要通過@JavascriptInterface來註解的Java函式才能被識別可以被Js呼叫。
三、設定當前網頁的連結仍在WebView中跳轉,而不是跳到手機瀏覽器裡顯示,
在WebViewClient的子類中重寫shouldOverrideUrlLoading函式 程式碼如下:
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
shouldOverrideUrlLoading表示當前webView中的一個新url需要載入時,給當前應用程式一個處理機會,如果沒有重寫此函式,webView請求ActivityManage選擇合適的方式處理請求,就像彈出uc和網際網路讓使用者選擇瀏覽器一樣。重寫後return true表示讓當前程式處理,return false表示讓當前webView處理四、設定開始載入網頁、載入完成、載入錯誤時處理
在WebViewClient子類中分別重寫如下父類函式 程式碼如下:
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
// 開始載入網頁時處理 如:顯示"載入提示" 的載入對話方塊
DialogManager.showLoadingDialog(this);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
// 網頁載入完成時處理 如:讓 載入對話方塊 消失
DialogManager.dismissLoadingDialog();
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
// 載入網頁失敗時處理 如:
view.loadDataWithBaseURL(null,
"<span style=\"color:#FF0000\">網頁載入失敗</span>",
"text/html",
"utf-8",
null);
}
});
五、處理https請求,為WebView處理ssl證照設定WebView預設是不處理https請求的,頁面顯示空白,需要進行如下設定
在WebViewClient子類中重寫父類的onReceivedSslError函式 程式碼如下:
webView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed(); // 接受信任所有網站的證照
// handler.cancel(); // 預設操作 不處理
// handler.handleMessage(null); // 可做其他處理
}
});
六、顯示頁面載入進度
在WebChromeClient子類中重寫父類的onProgressChanged函式 程式碼如下:
webView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
setTitle("頁面載入中,請稍候..." + progress + "%");
setProgress(progress * 100);
if (progress == 100) {
setTitle(R.string.app_name);
}
}
});
onProgressChanged通知應用程式當前頁面載入的進度progress表示當前頁面載入的進度,為1至100的整數
七、back鍵控制網頁後退
Activity預設的back鍵處理為結束當前Activity,WebView檢視了很多網頁後,希望按back鍵返回上一次瀏覽的頁面,這個時候我們就需要覆蓋WebView所在Activity的onKeyDown函式,告訴他如何處理,程式碼如下:
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (webView.canGoBack() && event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
其中webView.canGoBack()在webView含有一個可後退的瀏覽記錄時返回truewebView.goBack();表示返回至webView的上次訪問頁面
八、使用addJavascriptInterface完成和js互動
1、Js中調Native本地Java方法
設定webView的addJavascriptInterface方法,該方法有兩個引數,第一個引數為被繫結到js中的類例項,第二個引數為在js中暴露的類別名,在js中引用java物件就是用這個名字
在Native Java程式碼如下:
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new JavaScriptInterface(this), "Android");
class JavaScriptInterface{
Context mContext;
/** Instantiate the interface and set the context */
JavaScriptInterface(Context c) {
mContext = c;
}
/** Show a toast from the web page
* 由Js呼叫執行Native本地Java方法
*/
@JavascriptInterface
public void showToast(String toast) {
Log.d("TAG", "Js Invoker Native Function");
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
}
}
在HTML中Js呼叫Native方法 程式碼如下:
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />
<script type="text/javascript">
function showAndroidToast(toast) {
Android.showToast(toast);
}
</script>
2、Java調Js方法比如在HTML中有如下Js函式
<script type="text/javascript">
function showAlert() {
alert("Be executed by Native");
}
</script>
在Native調Js方法如下:
mWebView.loadUrl("javascript:showAlert()");
九、WebView快取模式的設定
1、網頁資料快取
當使用WebView載入HTML網頁時,會在我們data/應用package下生成database與cache兩個資料夾:
我們請求的Url記錄是儲存在webviewCache.db裡,而url的內容是儲存在webviewCache資料夾下.
五種快取模式的設定setCacheMode:
LOAD_CACHE_ONLY: 不使用網路,只讀取本地快取資料。
LOAD_DEFAULT: 根據cache-control決定是否從網路上取資料。
LOAD_CACHE_NORMAL: API level 17中已經廢棄, 從API level 11開始作用同LOAD_DEFAULT模式。
LOAD_NO_CACHE: 不使用快取,只從網路獲取資料。
LOAD_CACHE_ELSE_NETWORK,只要本地有,無論是否過期,或者no-cache,都使用快取中的資料。
如示例程式碼:
WebSettings webSettings = mWebView.getSettings();
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT); //設定 快取模式
// 開啟 DOM storage API 功能
webSettings.setDomStorageEnabled(true);
//開啟 database storage API 功能
webSettings.setDatabaseEnabled(true);
2、H5快取
通過setAppCacheEnabled(boolean flag)設定H5的快取是否開啟,預設關閉。
根據setAppCachePath(String appCachePath)提供的路徑,在H5使用快取過程中生成的快取檔案。
通過setAppCacheMaxSize(long appCacheMaxSize)設定快取最大容量。
如示例程式碼:
String cacheDirPath = getCacheDir().getAbsolutePath()+ "/webViewCache ";
WebSettings webSettings = mWebView.getSettings();
//開啟 database storage API 功能
webSettings.setDatabaseEnabled(true);
//設定資料庫快取路徑
webSettings.setDatabasePath(cacheDirPath);
//開啟Application H5 Caches 功能
webSettings.setAppCacheEnabled(true);
//設定Application Caches 快取目錄
webSettings.setAppCachePath(cacheDirPath);
十、加快HTML網頁載入完成速度
預設情況html程式碼下載到WebView後,webkit開始解析網頁各個節點,發現有外部樣式檔案或者外部指令碼檔案時,會非同步發起網路請求下載檔案,但如果在這之前也有解析到image節點,那勢必也會發起網路請求下載相應的圖片。在網路情況較差的情況下,過多的網路請求就會造成頻寬緊張,影響到css或js檔案載入完成的時間,造成頁面空白loading過久。解決的方法就是告訴WebView先不要自動載入圖片,等頁面finish後再發起圖片載入。
故在WebView初始化時設定如下程式碼:
public void int () {
if(Build.VERSION.SDK_INT >= 19) {
webView.getSettings().setLoadsImagesAutomatically(true);
} else {
webView.getSettings().setLoadsImagesAutomatically(false);
}
}
同時在WebView的WebViewClient子類中重寫onPageFinished()方法新增如下程式碼:
@Override
public void onPageFinished(WebView view, String url) {
if(!webView.getSettings().getLoadsImagesAutomatically()) {
webView.getSettings().setLoadsImagesAutomatically(true);
}
}
從上面的程式碼,可以看出我們對系統API在19以上的版本作了相容。因為4.4以上系統在onPageFinished時再恢復圖片載入時,如果存在多張圖片引用的是相同的src時,會只有一個image標籤得到載入,因而對於這樣的系統我們就先直接載入。十一、WebView硬體加速導致頁面渲染閃爍問題解決方法
關於Android硬體加速 開始於Android 3.0 (API level 11),在四個級別上開啟/關閉硬體加速
1、Application級別:為整個應用程式開啟硬體加速,在AndroidManifest中加入如下配置
<application android:hardwareAccelerated="true" ...>
2、Activity級別:控制每個activity是否開啟硬體加速,只需在activity元素中新增android:hardwareAccelerated屬性即可
<activity android:hardwareAccelerated="true" ...>
3、Window級別:注:目前還不支援在Window級別上關閉硬體加速
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
4、View級別:執行時單個view硬體加速,目前Android還不支援在View級別開啟硬體加速 程式碼如下:
mView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
[//TODO 關於Android硬體加速 小呂有時間會更詳細的單獨整理成一篇來做介紹
先提供學習地址:http://android.toolib.net/guide/topics/graphics/hardware-accel.html]
我們開啟硬體加速後,WebView渲染頁面更加快速,拖動也更加順滑。但有個副作用就是容易會出現頁面載入白塊同時介面閃爍現象。解決這個問題的方法是設定WebView暫時關閉硬體加速 程式碼如下:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
十二、WebView載入本地HTML檔案亂碼問題解決方案
分析一、保證html頁面有設定編碼格式 如:
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
分析二、為WebView 指定顯示的編碼,WebView設定編碼是在Settings中來設定,如:
mWebView.getSettings().setDefaultTextEncodingName("utf-8");
分析三、如果你是使用的loadData()來載入顯示網頁。中文出現亂碼 則改為loadDataWithBaseURL原因:webview.loadData方法不支援中文解析,通常用webView.loadDataWithBaseURL來解決。如:
//webview.loadData(data, "text/html", "utf-8");
webview.loadDataWithBaseURL(baseUrl, data, "text/html", "utf-8", failUrl);
十三、其他注意事項:
1> 從網路上下載html頁面的過程應放在工作執行緒(後臺執行緒)中2> html下載成功後渲染出html的步驟應放在UI主執行緒,不然WebView載入網頁過程會容易報錯
相關文章
- Android Webview 使用小結AndroidWebView
- Android混合開發之WebView使用總結AndroidWebView
- WebView深度學習(一)之WebView的基本使用以及Android和js的互動WebView深度學習AndroidJS
- 再學Android之WebViewAndroidWebView
- Android:Sqlitedatabase學習小結AndroidSQLiteDatabase
- Android開發小技巧之不再使用原生的WebView了AndroidWebView
- WebView深度學習(二)之全面總結WebView遇到的坑及優化WebView深度學習優化
- Android學習之 移動應用微信支付整合小結Android
- Android Webview和ScrollView衝突和WebView使用總結AndroidWebView
- android webview總結AndroidWebView
- WebView學習的總結————慕課網WebView
- 【C#學習之辨析小總結】C#
- 學習小結
- android WebView總結(轉)AndroidWebView
- Android中使用WebView遇到的問題總結:AndroidWebView
- vue 學習小結Vue
- JavaScript學習小結JavaScript
- NFS學習小結NFS
- Android webview使用詳解AndroidWebView
- Android中WebView使用解析AndroidWebView
- WebView的使用總結WebView
- 小程式學習總結
- git學習小總結Git
- CommonsChunkPlugin學習小結Plugin
- 整合學習原理小結
- Spring 學習小結Spring
- qDebug 學習小結
- 整合學習之Adaboost演算法原理小結演算法
- mysql學習之-小技巧MySql
- Android Camera 使用小結Android
- Android學習之 Scroller的介紹與使用Android
- Android之SurfaceView學習AndroidView
- 關於微信小程式webview的使用微信小程式WebView
- HTML5 學習小結HTML
- Activiti 學習筆記 小結筆記
- Thrift-java學習小結Java
- awk指令碼學習小結指令碼
- Android中WebView的使用指南:AndroidWebView