WebView在混合開發(fā)中很重要辛润,如果做純應用開發(fā)的話則很少接觸他,這里來梳理一下WebView的知識。
一 基本用法
1.1 Android View的一種用來展示網(wǎng)頁
- 在布局中添加WebView
- 使用WebView加載網(wǎng)頁
1.2 基本組件
- WebSettings:對WebView做各種設置
1.2.1 JS處理
- setJavaScriptEnabled(true); //支持js
- setPluginsEnabled(true); //支持插件
- setJavaScriptCanOpenWindowsAutomatically(true); //支持通過JS打開新窗口
1.2.2 縮放處理
- setUseWideViewPort(true); //將圖片調整到適合webview的大小
- setLoadWithOverviewMode(true); // 縮放至屏幕的大小
- setSupportZoom(true); //支持縮放外永,默認為true。是下面那個的前提拧咳。
- setBuiltInZoomControls(true); //設置內(nèi)置的縮放控件伯顶。 這個取決于setSupportZoom(), 若setSupportZoom(false),則該WebView不可縮放骆膝,這個不管設置什么都不能縮放祭衩。
- setDisplayZoomControls(false); //隱藏原生的縮放控件
1.2.3 內(nèi)容布局
- setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN); //支持內(nèi)容重新布局
- supportMultipleWindows(); //多窗口
1.2.4 文件緩存
- setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //關閉webview中緩存
- setAllowFileAccess(true); //設置可以訪問文件
1.2.5 其他設置
- setNeedInitialFocus(true); //當webview調用requestFocus時為webview設置節(jié)點
- setLoadsImagesAutomatically(true); //支持自動加載圖片
- setDefaultTextEncodingName("utf-8"); //設置編碼格式
- setPluginState(PluginState.OFF); //設置是否支持flash插件
- setDefaultFontSize(20); //設置默認字體大小
- WebViewClient:用來幫助WebView處理各種通知, 請求事件。繼承它實現(xiàn)定制阅签。
- shouldOverrideUrlLoading(WebView view, String url) //在網(wǎng)頁上的所有加載都經(jīng)過這個方法,這個函數(shù)我們可以做很多操作掐暮。比如獲取url,查看url.contains(“add”)政钟,進行添加操作
- shouldOverrideKeyEvent(WebView view, KeyEvent event) //處理在瀏覽器中的按鍵事件路克。
- onPageStarted(WebView view, String url, Bitmap favicon) //開始載入頁面時調用的樟结,我們可以設定一個loading的頁面,告訴用戶程序在等待網(wǎng)絡響應精算。
- onPageFinished(WebView view, String url) //在頁面加載結束時調用, 我們可以關閉loading 條瓢宦,切換程序動作。
- onLoadResource(WebView view, String url) //在加載頁面資源時會調用灰羽,每一個資源(比如圖片)的加載都會調用一次驮履。
- onReceivedError(WebView view, int errorCode, String description, String failingUrl) //報告錯誤信息
- doUpdateVisitedHistory(WebView view, String url, boolean isReload) //更新歷史記錄
- onFormResubmission(WebView view, Message dontResend, Message resend) //應用程序重新請求網(wǎng)頁數(shù)據(jù)
- onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host,String realm) //獲取返回信息授權請求
- onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) //讓webview處理https請求。
- onScaleChanged(WebView view, float oldScale, float newScale) //WebView發(fā)生改變時調用
- onUnhandledKeyEvent(WebView view, KeyEvent event) //Key事件未被加載時調用
- WebChromeClient:幫助WebView處理JS的對話框谦趣、網(wǎng)址圖標疲吸、網(wǎng)址標題和加載進度等。
- public void onProgressChanged(WebView view, int newProgress); //獲得網(wǎng)頁的加載進度前鹅,顯示在右上角的TextView控件中
- public void onReceivedTitle(WebView view, String title); //獲取Web頁中的title用來設置自己界面中的title, 當加載出錯的時候,比如無網(wǎng)絡峭梳,這時onReceiveTitle中獲取的標題為"找不到該網(wǎng)頁",
- public void onReceivedIcon(WebView view, Bitmap icon); //獲取Web頁中的icon
- public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg);
- public void onCloseWindow(WebView window);
- public boolean onJsAlert(WebView view, String url, String message, JsResult result); //處理alert彈出框舰绘,html 彈框的一種方式
- public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) //處理confirm彈出框
- public boolean onJsConfirm(WebView view, String url, String message, JsResult result); //處理prompt彈出框
生命周期
- onResume(): WebView為活躍狀態(tài)時回調,可以正常執(zhí)行網(wǎng)頁的響應葱椭。
- onPause(): WebView被切換到后臺時回調, 頁面被失去焦點, 變成不可見狀態(tài)捂寿,onPause動作通知內(nèi)核暫停所有的動作,比如DOM的解析孵运、plugin的執(zhí)行秦陋、JavaScript執(zhí)行。
- pauseTimers(): 當應用程序被切換到后臺時回調治笨,該方法針對全應用程序的WebView驳概,它會暫停所有webview的layout,parsing旷赖,javascripttimer顺又。降低CPU功耗。
- resumeTimers(): 恢復pauseTimers時的動作等孵。
-
destroy():關閉了Activity時回調, WebView調用destory時, WebView仍綁定在Activity上.這是由于自定義WebView構建時傳入了該Activity的context對象, 因此需要先從父容器中移除WebView, 然后再銷毀webview稚照。
頁面導航
頁面跳轉
當我們在WebView點擊鏈接時, 默認的WebView會直接跳轉到別的瀏覽器中, 如果想要實現(xiàn)在WebView內(nèi)跳轉就需要設置WebViewClient
WebView、WebViewClient俯萌、WebChromeClient三者的區(qū)別
- WebView: 主要負責解析和渲染網(wǎng)頁
- WebViewClient: 輔助WebView處理各種通知和請求事件
- WebChromeClient: 輔助WebView處理JavaScript中的對話框, 網(wǎng)址圖標和標題等
控制不同鏈接的跳轉方式
繼承WebViewClient重寫shouldOverrideUrlLoading()方法
方法的兩點說明
- 方法返回值
返回true: Android 系統(tǒng)會處理URL, 一般是喚起系統(tǒng)瀏覽器果录。 返回false: 當前 WebView 處理URL。 -
方法deprecated問題
API >= 24時被標記deprecated, 它的替代方法是
頁面回退
重寫onKeyEvent()方法
頁面滑動
- 三個判斷高度的方法
getScrollY();當前內(nèi)容滾動的距離
getHeight(); getBottom();都返回當前WebView這個容器的高度
getContentHeight(); 整個html的高度, 但并不等同于當前整個頁面的高度咐熙。因為WebView有縮放功能, 所以當前整個頁面的高度實際上應該是原始html的高度 再乘上縮放比例. -
判斷WebView是否滾動到頂部或底部
API 17開始, mWebView.getScale()被標記為deprecate弱恒,獲取新的Scale。
緩存實現(xiàn)
- 加載html頁面時, 會在/data/data/包名目錄下生成database與cache兩個文件夾糖声。
- 請求的url記錄是保存在WebViewCache.db, 而url的內(nèi)容是保存在WebViewCache文件夾下斤彼。
-
控制緩存行為
清除緩存
本地資源訪問
- html內(nèi)容先下載到本地分瘦,然后使用loadDataWithBaseURL加載html。這樣就可以在html中使用 [file:///android_asset/xxx.png](file:///android_asset/xxx.png)的鏈接來引用包里 面assets下的資源了琉苇。
- 注意事項
從網(wǎng)絡上下載html的過程應放在工作線程中
html下載成功后渲染出html的步驟應放在UI主線程嘲玫,不然WebView會報錯
html下載失敗則可以使用我們前面講述的方法來顯示自定義錯誤界面
二 代碼交互
Android原生方案
- JavaScript代碼和Android代碼是通過addJavascriptInterface()來建立連接的
1. 設置WebView支持JavaScript
2. webView.getSettings().setJavaScriptEnabled(true);
3. 在Android工程里定義一個接口WebAppInterface
4. API >= 17時, 被JavaScript調用的Android方法前添加@JavascriptInterface注解, 否則將無法識別。
5. Android代碼中將該接口添加到WebView
webView.addJavascriptInterface(new WebAppInterface(this), "Android");
"Android"就是我們?yōu)檫@個接口取的別名, 在JavaScript就可以通過Android.showToast(toast)這種方式來調用此方法并扇。
-
在JavaScript中調用Android方法
JavaScript中我們不用再去實例化WebAppInterface接口
- 由于addJavascriptInterface()給予了JS代碼控制應用的能力, 這是一項非常有用的特性, 但同時也帶來了安全上的隱患,
jockeyjs開源方案
- jockeyjs是一套IOS/Android雙平臺的Native和JS交互方法, 比較適合用在項目中
- jockeyjs對Native和JS的交互做了優(yōu)美的封裝, 事件的發(fā)送與接收都可以通過send()和on()來完成去团。
三 性能優(yōu)化
-
優(yōu)化網(wǎng)頁加載速度
原因:webkit解析網(wǎng)頁各個節(jié)點,當有圖片加載時會影響css或者js文件加載
解決辦法: 設置WebView, 先禁止加載圖片
覆寫WebViewClient的onPageFinished()方法, 頁面加載結束后再加載圖片
4.4以上系統(tǒng)在onPageFinished時再恢復圖片加載時,如果存在多張圖片引用的是相同的src時,會只有一個image標簽得到加載穷蛹,因而對于這樣的系統(tǒng)我們就先直接加載土陪。 -
硬件加速頁面閃爍問題
原因:當WebView視圖被整體遮住一塊,然后突然恢復時(比如使用SlideMenu將WebView從側邊 滑出來時)肴熏,這個過渡期會出現(xiàn)白塊同時界面閃爍鬼雀。
解決辦法:在過渡期前將WebView的硬件加速臨時關閉,過渡期后再開啟
過度后開啟硬件加速
以上就是我對webView的總結蛙吏。