Android中WebView的使用,載入H5
1、WebView簡介
WebView
是Android
用於顯示Web網頁的一種控制元件;WebView
內部實現是採用渲染引擎來展示view的內容,提供網頁前進後退,網頁放大,縮小,搜尋;在低版本和高版本採用了不同的webkit版本核心,andoid 4.4後直接使用Chrome
。
現在很多APP(Hybrid App
)都內建了Web網頁,比如說很多電商平臺,淘寶、天貓、京東、聚划算等等。WebView
比較靈活,不需要升級客戶端,只需要修改網頁程式碼即可。一些經常變化的頁面可以用WebView
這種方式去載入網頁。例如中秋節跟國慶節開啟的頁面不一樣,如果是用WebView
顯示的話,只修改修改html頁面就行,而不需要升級客戶端。
2、使用介紹
2.1、載入HTML方式
//方式1. 載入一個網頁: webView.loadUrl("http://www.baidu.com/"); //方式2:載入asset中的html頁面 webView.loadUrl("file:///android_asset/test.html"); //方式3:載入手機本地SD卡的html頁面 webView.loadUrl("content://com.android.htmlfileprovider/sdcard/test.html"); // 方式4: 載入 HTML 頁面的一小段內容 // 引數說明: // 引數1:需要擷取展示的內容 // 內容裡不能出現 ’#’, ‘%’, ‘\’ , ‘?’ 這四個字元,若出現了需用 %23, %25, %27, %3f 對應來替代,否則會出現異常 // 引數2:展示內容的型別 // 引數3:位元組碼 WebView.loadData(String data, String mimeType, String encoding) //方式5 使用webview顯示html程式碼 webView.loadDataWithBaseURL(null,"<html><head><title> 歡迎您 </title></head>" + "<body><h2>使用webview顯示 html程式碼</h2></body></html>", "text/html" , "utf-8", null);
2.2、WebView常用方法
//啟用WebView為活躍狀態,能正常執行網頁的響應 webView.onResume() ; //當頁面被失去焦點被切換到後臺不可見狀態,需要執行onPause //通過onPause動作通知核心暫停所有的動作,比如DOM的解析、plugin的執行、JavaScript執行。 webView.onPause(); //是否可以後退 Webview.canGoBack() //後退網頁 Webview.goBack() //是否可以前進 Webview.canGoForward() //前進網頁 Webview.goForward() //以當前的index為起始點前進或者後退到歷史記錄中指定的steps //如果steps為負數則為後退,正數則為前進 Webview.goBackOrForward(intsteps) //清除網頁訪問留下的快取 //由於核心快取是全域性的因此這個方法不僅僅針對webview而是針對整個應用程式. Webview.clearCache(true); //清除當前webview訪問的歷史記錄 //只會webview訪問歷史記錄裡的所有記錄除了當前訪問記錄 Webview.clearHistory(); //這個api僅僅清除自動完成填充的表單資料,並不會清除WebView儲存到本地的資料 Webview.clearFormData();
2.3、工具類WebSetting
WebSetting
用於配置和管理WebView
@SuppressLint("SetJavaScriptEnabled") private fun initWebSetting() { //宣告WebSettings子類 val webSettings = mWebView.settings //如果訪問的頁面中要與Javascript互動,則webView必須設定支援Javascript // 若載入的 html 裡有JS 在執行動畫等操作,會造成資源浪費(CPU、電量) // 在 onStop 和 onResume 裡分別把 setJavaScriptEnabled() 給設定成 false 和 true 即可 webSettings.javaScriptEnabled = true // 設定允許JS彈窗 webSettings.javaScriptCanOpenWindowsAutomatically = true //設定自適應螢幕,兩者合用 webSettings.useWideViewPort = true //將圖片調整到適合webView的大小 webSettings.loadWithOverviewMode = true // 縮放至螢幕的大小 //縮放操作 webSettings.setSupportZoom(true) //支援縮放,預設為true。是下面那個的前提。 webSettings.builtInZoomControls = true //設定內建的縮放控制元件。若為false,則該WebView不可縮放 webSettings.displayZoomControls = false //隱藏原生的縮放控制元件 //其他細節操作 webSettings.cacheMode = WebSettings.LOAD_CACHE_ELSE_NETWORK //關閉webView中快取 webSettings.allowFileAccess = true //設定可以訪問檔案 webSettings.javaScriptCanOpenWindowsAutomatically = true //支援通過JS開啟新視窗 webSettings.loadsImagesAutomatically = true //支援自動載入圖片 webSettings.defaultTextEncodingName = "utf-8"//設定編碼格式 // 特別注意:5.1以上預設禁止了https和http混用,以下方式是開啟 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { webSettings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW } }
2.4、WebViewClient
WebViewClient
主要幫助WebView
處理各種通知、請求事件的,有以下常用方法:
onPageFinished onPageStarted onLoadResource shouldOverrideUrlLoading onReceivedError onReceivedSslError
//使得開啟網頁時不呼叫系統瀏覽器, 而是在本WebView中顯示 mWebView.webViewClient = object : CompatWebViewClient() { override fun onLoadResource(view: WebView?, url: String?) { Log.i(TAG, "Resource$url") } override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { Log.i(TAG, "開始載入:$url") } override fun onPageFinished(view: WebView?, url: String?) { Log.i(TAG, "結束載入:$url") } override fun onReceivedError(view: WebView?, errorCode: Int, description: String?, failingUrl: String?) { //載入失敗,顯示本地網頁 Log.i(TAG, "errorCode: $errorCode$failingUrl") } override fun onReceivedSslError(view: WebView?, handler: SslErrorHandler?, error: SslError?) { // 如果實現呼叫了handler.proceed()來忽略該證書錯誤,則會受到中間人攻擊的威脅,可能導致隱私洩露 //修復方式: //【1】不呼叫android.webkit.SslErrorHandler的proceed方法 //【2】當發生證書認證錯誤時,採用預設的處理方法SslErrorHandler.cancel(),停止載入問題頁面 } override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { return super.shouldOverrideUrlLoading(view, url) } }
2.5、WebChromeClient
WebChromeClient
主要輔助WebView
處理Javascript
的對話方塊、網站圖示、網站title、載入進度等,有以下常用方法。
-
onJsAlert
webview
不支援javascript
的alert彈窗,需要自己監聽然後通過dialog彈窗 -
onJsConfirm
javascript
的確認框 -
onJsPrompt
javascript
的輸入框 -
onReceivedTitle
獲取網頁標題 -
onReceivedIcon
獲取網頁圖示icon -
onProgressChanged
載入進度回撥
mWebView.webChromeClient = object : WebChromeClient() { override fun onReceivedTitle(view: WebView?, title: String?) { Log.i(TAG, "title: $title${view?.url}") } override fun onReceivedIcon(view: WebView?, icon: Bitmap?) { } override fun onProgressChanged(view: WebView?, newProgress: Int) { Log.i(TAG, "progress: $newProgress${view?.url}") } override fun onJsAlert(view: WebView?, url: String?, message: String?, result: JsResult?): Boolean { //警告框 AlertDialog.Builder(this@MainActivity) .setTitle("JsAlert") .setMessage(message) .setPositiveButton("OK") { _, _ -> result?.confirm() } .setCancelable(false) .show() return true } override fun onJsConfirm(view: WebView?, url: String?, message: String?, result: JsResult?): Boolean { //確認框 AlertDialog.Builder(this@MainActivity) .setTitle("JsConfirm") .setMessage(message) .setPositiveButton("OK") { _, _ -> result?.confirm() } .setNegativeButton("Cancel") { _, _ -> result?.cancel() } .setCancelable(false) .show() return true } override fun onJsPrompt( view: WebView?, url: String?, message: String?, defaultValue: String?, result: JsPromptResult? ): Boolean { //輸入框 AlertDialog.Builder(this@MainActivity) .setTitle(message) .setView(EditText(this@MainActivity)) .setPositiveButton("OK") { _, _ -> result?.confirm() } .setNegativeButton("Cancel") { _, _ -> result?.cancel() } .setCancelable(false) .show() return true } }
2.6、防止記憶體洩漏
1、不在佈局檔案xml中設定佈局,通過程式碼的方式new
一個WebView
物件,然後新增到佈局中
val mWebView=WebView(applicationContext) mLinLayout.addView(mWebView,params)
2、Activity
退出時銷燬WebView
protected fun onDestroy() { if (mWebView != null) { // 如果先呼叫destroy()方法,則會命中if (isDestroyed()) return;這一行程式碼, //需要先onDetachedFromWindow(),再destory() val parent = mWebView.parent if (parent != null) { (parent as ViewGroup).removeView(mWebView) } mWebView.stopLoading() // 退出時呼叫此方法,移除繫結的服務,否則某些特定系統會報錯 mWebView.settings.javaScriptEnabled = false mWebView.clearHistory() mWebView.removeAllViews() mWebView.destroy() } super.onDestroy() }
參考:ofollow,noindex">https://www.jianshu.com/p/3c94ae673e2a