Android WebView 全面解析

一、簡介

為了方便開發(fā)者實現(xiàn)在app內(nèi)展示網(wǎng)頁并與網(wǎng)頁交互的需求,Android SDK提供了WebView組件。它繼承自AbsoluteLayout堤魁,展示網(wǎng)頁的同時,也可以在其中放入其他的子View》凳現(xiàn)如今妥泉,Hybrid應用似乎占據(jù)的APP的主流類型,那么關于WebView的使用就變得越發(fā)的重要吧慢。從Android 4.4(KitKat)開始涛漂,原本基于WebKit的WebView開始基于Chromium內(nèi)核赏表,這一改動大大提升了WebView組件的性能以及對HTML5,CSS3,JavaScript的支持检诗。

二、相關類及API

1瓢剿、WebView

基本:

  • String getUrl():獲取當前頁面的URL逢慌。
  • String getTitle():獲取當前頁面的標題。
  • Bitmap getFavicon():獲取當前頁面的favicon
  • int getProgress():獲取當前頁面的加載進度
  • setInitialScale(int scaleInPercent):設置初始縮放比例

加載網(wǎng)頁:

  • loadUrl(String url):加載URL指定的網(wǎng)頁
  • loadUrl(String url, Map<String, String> additionalHttpHeaders):攜帶http headers加載URL指定的網(wǎng)頁
  • postUrl(String url, byte[] postData):使用POST請求加載指定的網(wǎng)頁
  • reload():重新reload當前的URL间狂,即刷新攻泼。
  • loadData(String data, String mimeType, String encoding):加載內(nèi)容
  • loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl):使用baseUrl加載內(nèi)容

導航:

  • boolean canGoBack():用來確認WebView里是否還有可回退的歷史記錄。通常我們會在WebView里重寫返回鍵的點擊事件,通過該方法判斷WebView里是否還有歷史記錄忙菠,若有則返回上一頁何鸡。
  • boolean canGoForward():用來確認WebView是否還有可向前的歷史記錄。
  • boolean canGoBackOrForward(int steps):以當前的頁面為起始點牛欢,用來確認WebView的歷史記錄是否足以后退或前進給定的步數(shù)骡男,正數(shù)為前進,負數(shù)為后退傍睹。
  • goBack():在WebView歷史記錄后退到上一項隔盛。
  • goForward():在WebView歷史記錄里前進到下一項。
  • goBackOrForward(int steps):以當前頁面為起始點拾稳,前進或后退歷史記錄中指定的步數(shù)吮炕,正數(shù)為前進,負數(shù)為后退访得。
  • WebBackForwardList copyBackForwardList():復制一份BackForwardList
  • clearHistory():清除當前webview訪問的歷史記錄龙亲。

JavaScript:

  • addJavascriptInterface(Object object, String name):注入Javascript對象
  • removeJavascriptInterface(String name):移除已注入的Javascript對象,下次加載或刷新頁面時生效
  • evaluateJavascript(String script, ValueCallback<String> resultCallback):對傳入的JS表達式求值震鹉,通過resultCallback返回結(jié)果俱笛。此函數(shù)添加于API19,必須在UI線程中調(diào)用传趾,回調(diào)也將在UI線程

其他:

  • findAllAsync (String find):異步執(zhí)行查找網(wǎng)頁內(nèi)包含的字符串并設置高亮迎膜,查找結(jié)果會回調(diào)
  • findNext (boolean forward): 查找下一個匹配的字符串
  • setFindListener(FindListener listener):設置網(wǎng)頁查找結(jié)果回調(diào)
  • clearMatches():清除網(wǎng)頁查找的高亮匹配字符串
  • saveWebArchive(String filename):保存網(wǎng)頁(.html)到指定文件
  • saveWebArchive(String basename, boolean autoname, ValueCallback<String> callback):保存網(wǎng)頁(.html)到文件
  • pageUp(boolean top):將WebView展示的頁面滑動至頂部。
  • pageDown(boolean bottom):將WebView展示的頁面滑動至底部浆兰。
  • zoomBy(float factor):縮放
  • zoomIn():放大
  • zoomOut():縮放
  • clearCache(boolean includeDiskFiles):清空網(wǎng)頁訪問留下的緩存數(shù)據(jù)磕仅。需要注意的時,由于緩存是全局的簸呈,所以只要是WebView用到的緩存都會被清空榕订,即便其他地方也會使用到。該方法接受一個參數(shù)蜕便,從命名即可看出作用劫恒。若設為false,則只清空內(nèi)存里的資源緩存轿腺,而不清空磁盤里的两嘴。
  • clearFormData():清除自動完成填充的表單數(shù)據(jù)。需要注意的是族壳,該方法僅僅清除當前表單域自動完成填充的表單數(shù)據(jù)憔辫,并不會清除WebView存儲到本地的數(shù)據(jù)。
  • clearSslPreferences():清除SSL偏好
  • onPause():當頁面被失去焦點被切換到后臺不可見狀態(tài)仿荆,需要執(zhí)行onPause操作贰您,該操作會通知內(nèi)核安全地暫停所有動作坏平,比如動畫的執(zhí)行或定位的獲取等。需要注意的是該方法并不會暫停JavaScript的執(zhí)行锦亦,若要暫停JavaScript的執(zhí)行請使用接下來的這個方法舶替。
  • onResume():在先前調(diào)用onPause()后,我們可以調(diào)用該方法來恢復WebView的運行杠园。
  • pauseTimers():該方法面向全局整個應用程序的webview坎穿,它會暫停所有webview的layout,parsing返劲,JavaScript Timer玲昧。當程序進入后臺時,該方法的調(diào)用可以降低CPU功耗篮绿。
  • resumeTimers():恢復pauseTimers時的所有操作孵延。
  • destroy():銷毀WebView。需要注意的是:這個方法的調(diào)用應在WebView從父容器中被remove掉之后亲配。我們可以手動地調(diào)用
  • getContentHeight():該方法返回整個HTML頁面的高度尘应,但該高度值并不等同于當前整個頁面的高度,因為WebView有縮放功能吼虎, 所以當前整個頁面的高度實際上應該是原始HTML的高度再乘上縮放比例

2犬钢、WebSettings

  • setDomStorageEnabled(boolean flag):啟用HTML5 DOM storage API,默認值 false
  • setDatabaseEnabled(boolean flag):啟用Web SQL Database API思灰,這個設置會影響同一進程內(nèi)的所有WebView玷犹,默認值 false,此API已不推薦使用
  • setAppCacheEnabled(boolean flag):啟用Application Caches API洒疚,必需設置有效的緩存路徑才能生效歹颓,默認值 false,此API已廢棄
  • setAppCachePath(String appCachePath):設值緩存路徑
  • setGeolocationEnabled(boolean flag):啟用定位
  • setSaveFormData(boolean save):是否保存表單數(shù)據(jù)
  • setNeedInitialFocus(boolean flag):是否當webview調(diào)用requestFocus時為頁面的某個元素設置焦點油湖,默認值 true
  • setUseWideViewPort(boolean use):是否支持viewport屬性巍扛,默認值 false, 頁面通過<meta name="viewport" ... />自適應手機屏幕
  • setLoadWithOverviewMode(boolean overview):是否使用overview mode加載頁面乏德,默認值 false撤奸,當頁面寬度大于WebView寬度時,縮小使頁面寬度等于WebView寬度
  • setLayoutAlgorithm(LayoutAlgorithm l):布局算法喊括,默認是LayoutAlgorithm#NARROW_COLUMNS
  • setJavaScriptEnabled(boolean flag):是否支持Javascript胧瓜,默認值false
  • setSupportMultipleWindows(boolean support):是否支持多窗口,默認值false
  • setJavaScriptCanOpenWindowsAutomatically(boolean flag):是否可用Javascript(window.open)打開窗口瘾晃,默認值 false
  • setAllowContentAccess(boolean allow):/是否可訪問Content Provider的資源贷痪,默認值 true
  • setAllowFileAccess(boolean allow):是否可訪問本地文件幻妓,默認值 true
  • setAllowFileAccessFromFileURLs(boolean flag):是否允許通過file url加載的Javascript讀取本地文件蹦误,默認值 false
  • setAllowUniversalAccessFromFileURLs(boolean flag):是否允許通過file url加載的Javascript讀取全部資源(包括文件,http,https)劫拢,默認值 false
  • setLoadsImagesAutomatically(boolean flag):是否自動加載圖片
  • setBlockNetworkImage(boolean flag):禁止加載網(wǎng)絡圖片
  • setBlockNetworkLoads(boolean flag):禁止加載所有網(wǎng)絡資源
  • setSupportZoom(boolean support):是否支持縮放
  • setBuiltInZoomControls(boolean enabled):是否使用內(nèi)置縮放機制
  • setDisplayZoomControls(boolean enabled):是否顯示內(nèi)置縮放控件
  • setDefaultTextEncodingName(String encoding):設置文本編碼
  • setDefaultFontSize(int size):設置默認字體大小
  • setDefaultFixedFontSize(int size):默認等寬字體尺寸
  • setMinimumFontSize(int size):最小文字尺寸,默認值 8
  • setMinimumLogicalFontSize(int size):最小文字邏輯尺寸强胰,默認值 8
  • setTextZoom(int textZoom):文字縮放百分比舱沧,默認值 100
  • setStandardFontFamily(String font):標準字體,默認值 "sans-serif"
  • setSerifFontFamily(String font):襯線字體偶洋,默認值 "serif"
  • setSansSerifFontFamily(String font):無襯線字體熟吏,默認值 "sans-serif"
  • setFixedFontFamily(String font):等寬字體,默認值 "monospace"
  • setCursiveFontFamily(String font):手寫體玄窝,默認值 "cursive"
  • setFantasyFontFamily(String font):幻想體牵寺,默認值 "fantasy"
  • setMediaPlaybackRequiresUserGesture(boolean require):用戶是否需要通過手勢播放媒體(不會自動播放),默認值 true
  • setOffscreenPreRaster(boolean enabled):是否在離開屏幕時光柵化(會增加內(nèi)存消耗)恩脂,默認值 false
  • setCacheMode(@CacheMode int mode):用來設置WebView的緩存模式帽氓。當我們加載頁面或從上一個頁面返回的時候,會按照設置的緩存模式去檢查并使用(或不使用)緩存俩块。
    緩存模式有四種:
    • LOAD_DEFAULT:默認的緩存使用模式黎休。在進行頁面前進或后退的操作時,如果緩存可用并未過期就優(yōu)先加載緩存玉凯,否則從網(wǎng)絡上加載數(shù)據(jù)势腮。這樣可以減少頁面的網(wǎng)絡請求次數(shù)。
    • LOAD_CACHE_ELSE_NETWORK:只要緩存可用就加載緩存漫仆,哪怕它們已經(jīng)過期失效捎拯。如果緩存不可用就從網(wǎng)絡上加載數(shù)據(jù)。
    • LOAD_NO_CACHE:不加載緩存盲厌,只從網(wǎng)絡加載數(shù)據(jù)玄渗。
    • LOAD_CACHE_ONLY:不從網(wǎng)絡加載數(shù)據(jù),只從緩存加載數(shù)據(jù)狸眼。
      通常我們可以根據(jù)網(wǎng)絡情況將這幾種模式結(jié)合使用藤树,比如有網(wǎng)的時候使用LOAD_DEFAULT,離線時使用LOAD_CACHE_ONLY拓萌、LOAD_CACHE_ELSE_NETWORK岁钓,讓用戶不至于在離線時啥都看不到

3、WebViewClient

從名字上不難理解微王,這個類就像WebView的委托人一樣屡限,是幫助WebView處理各種通知和請求事件的

  • public boolean shouldOverrideUrlLoading(WebView view, String url)
    攔截頁面加載,返回true表示宿主app攔截并處理了該url炕倘,否則返回false由當前WebView處理
    此方法在API24被廢棄钧大,不處理POST請求

  • public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
    攔截頁面加載,返回true表示宿主app攔截并處理了該url罩旋,否則返回false由當前WebView處理
    此方法添加于API24啊央,不處理POST請求眶诈,可攔截處理子frame的非http請求

  • public WebResourceResponse shouldInterceptRequest(WebView view, String url)
    此方法廢棄于API21,調(diào)用于非UI線程攔截資源請求并返回響應數(shù)據(jù)瓜饥,返回null時WebView將繼續(xù)加載資源读规。注意:API21以下的AJAX請求會走onLoadResource励稳,無法通過此方法攔截

  • public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request)
    此方法添加于API21,調(diào)用于非UI線程,攔截資源請求并返回數(shù)據(jù)揣炕,返回null時WebView將繼續(xù)加載資源

  • public void onPageStarted(WebView view, String url, Bitmap favicon)
    頁面(url)開始加載

  • public void onPageFinished(WebView view, String url)
    頁面(url)完成加載

  • public void onLoadResource(WebView view, String url)
    將要加載資源(url)

  • public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
    此方法廢棄于API23鄙煤, 主框架加載資源時出錯

  • public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error)
    此方法添加于API23离唬,加載資源時出錯凿歼,通常意味著連接不到服務器。由于所有資源加載錯誤都會調(diào)用此方法食磕,所以此方法應盡量邏輯簡單

  • public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse)
    此方法添加于API23谣光, 在加載資源(iframe,image,js,css,ajax...)時收到了 HTTP 錯誤(狀態(tài)碼>=400)

  • public void onFormResubmission(WebView view, Message dontResend, Message resend)
    是否重新提交表單,默認不重發(fā)

  • public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error)
    加載資源時發(fā)生了一個SSL錯誤芬为,應用必需響應(繼續(xù)請求或取消請求)萄金, 處理決策可能被緩存用于后續(xù)的請求,默認行為是取消請求

  • public void onReceivedClientCertRequest(WebView view, ClientCertRequest request)
    此方法添加于API21媚朦,在UI線程被調(diào)用氧敢, 處理SSL客戶端證書請求,必要的話可顯示一個UI來提供KEY询张。
    有三種響應方式:proceed()/cancel()/ignore()孙乖,默認行為是取消請求
    如果調(diào)用proceed()或cancel(),Webview 將在內(nèi)存中保存響應結(jié)果且對相同的"host:port"不會再次調(diào)用 onReceivedClientCertRequest
    多數(shù)情況下份氧,可通過KeyChain.choosePrivateKeyAlias啟動一個Activity供用戶選擇合適的私鑰

  • public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm)
    處理HTTP認證請求唯袄,默認行為是取消請求

  • public void onReceivedLoginRequest(WebView view, String realm, String account, String args)
    通知應用有個已授權(quán)賬號自動登陸了

  • public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event)
    給應用一個機會處理按鍵事件,如果返回true蜗帜,WebView不處理該事件恋拷,否則WebView會一直處理,默認返回false

  • public void onScaleChanged(WebView view, float oldScale, float newScale)
    通知應用頁面縮放系數(shù)變化

一些關鍵方法調(diào)用流程:

  • loadUrl()無重定向時

    onPageStarted->onPageFinished

  • loadUrl()網(wǎng)頁A重定向到B時

    onPageStarted->shouldOverrideUrlLoading->onPageStarted->onPageFinished->onPageFinished

  • 在已加載的頁面中點擊鏈接厅缺,加載頁面A(無重定向)

    shouldOverrideUrlLoading->onPageStarted->onPageFinished

  • 在已加載的頁面中點擊鏈接蔬顾,加載頁面A(頁面A重定向至頁面B)

    shouldOverrideUrlLoading->onPageStarted->shouldOverrideUrlLoading->onPageStarted->onPageFinished->onPageFinished

  • 執(zhí)行g(shù)oBack/goForward/reload方法

    onPageStarted->onPageFinished

  • 發(fā)生資源加載

    shouldInterceptRequest->onLoadResource

  • 頁面加載

    shouldOverrideUrlLoading
    onProgressChanged[10]
    shouldInterceptRequest
    onProgressChanged[...]
    onPageStarted
    onProgressChanged[...]
    onLoadResource
    onProgressChanged[...]
    onReceivedTitle/onPageCommitVisible
    onProgressChanged[100]
    onPageFinished
    onReceivedIcon

4、WebChromeClient

  • public void getVisitedHistory(ValueCallback<String[]> callback)
    獲得所有訪問歷史項目的列表湘捎,用于鏈接著色诀豁。

  • public Bitmap getDefaultVideoPoster()
    <video /> 控件在未播放時,會展示為一張海報圖窥妇,HTML中可通過它的'poster'屬性來指定舷胜。
    如果未指定'poster'屬性,則通過此方法提供一個默認的海報圖活翩。

  • public View getVideoLoadingProgressView()
    當全屏的視頻正在緩沖時烹骨,此方法返回一個占位視圖(比如旋轉(zhuǎn)的菊花)翻伺。

  • public void onProgressChanged(WebView view, int newProgress)
    接收當前頁面的加載進度

  • public void onReceivedTitle(WebView view, String title)
    接收文檔標題

  • public void onReceivedIcon(WebView view, Bitmap icon)
    接收圖標(favicon)

  • public void onShowCustomView(View view, CustomViewCallback callback)
    通知應用當前頁進入了全屏模式,此時應用必須顯示一個包含網(wǎng)頁內(nèi)容的自定義View

  • public void onHideCustomView()
    通知應用當前頁退出了全屏模式展氓,此時應用必須隱藏之前顯示的自定義View

  • public boolean onJsAlert(WebView view, String url, String message, JsResult result)
    顯示一個alert對話框

  • public boolean onJsConfirm(WebView view, String url, String message, JsResult result)
    顯示一個confirm對話框

  • public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result)
    顯示一個prompt對話框

  • public boolean onJsBeforeUnload(WebView view, String url, String message, JsResult result)
    顯示一個對話框讓用戶選擇是否離開當前頁面

  • public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback)
    指定源的網(wǎng)頁內(nèi)容在沒有設置權(quán)限狀態(tài)下嘗試使用地理位置API。
    從API24開始脸爱,此方法只為安全的源(https)調(diào)用遇汞,非安全的源會被自動拒絕

  • public void onGeolocationPermissionsHidePrompt()
    當前一個調(diào)用 onGeolocationPermissionsShowPrompt() 取消時,隱藏相關的UI簿废。

  • public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg)
    通知應用打開新窗口

  • public void onCloseWindow(WebView window)
    通知應用關閉窗口

  • public void onRequestFocus(WebView view)
    請求獲取取焦點

  • public void onPermissionRequest(PermissionRequest request)
    通知應用網(wǎng)頁內(nèi)容申請訪問指定資源的權(quán)限(該權(quán)限未被授權(quán)或拒絕)

  • public void onPermissionRequestCanceled(PermissionRequest request)
    通知應用權(quán)限的申請被取消空入,隱藏相關的UI。

  • public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams)
    為'<input type="file" />'顯示文件選擇器族檬,返回false使用默認處理

  • public boolean onConsoleMessage(ConsoleMessage consoleMessage)
    接收JavaScript控制臺消息

5歪赢、CookieManager

  • CookieManager getInstance():獲得一個CookieManager實例
  • String getCookie(String url):根據(jù)url獲取Cookie,以字符串形式返回Cookie
  • void setCookie(String url, String value):為url設置Cookie
  • void setCookie(String url, String value, ValueCallback<Boolean> callback)
    callback的onReceiveValue方法獲取的參數(shù)如果是true单料,代表本次設置成功埋凯,否則代表設置失敗。如果并不關心執(zhí)行結(jié)果扫尖,為callback參數(shù)傳入null即可
  • void setAcceptCookie(boolean accept):設置WebView是否允許使用Cookie白对,這個方法針對的是當前應用的所有WebView。
  • void setAcceptThirdPartyCookies(WebView webview, boolean accept):設置WebView是否允許設置第三方Cookie换怖,Android 5.0(API 21)以下默認為true甩恼,Android 5.0及以上默認為false
  • void removeSessionCookie():移除所有Session Cookies ,Android 5.0(API 21)已棄用
  • void removeSessionCookies(ValueCallback<Boolean> callback):移除所有Session Cookies(異步執(zhí)行)沉颂,在執(zhí)行完移除操作后条摸,會回調(diào)onReceiveValue方法
  • void removeAllCookie():移除所有Cookies ,Android 5.0(API 21)已棄用
  • void removeAllCookies(ValueCallback<Boolean> callback):移除所有Cookies(異步執(zhí)行)
  • boolean hasCookies():判斷是否存在Cookies
  • void removeExpiredCookie():移除過期的Cookies

三铸屉、特殊場景介紹

1钉蒲、視口(viewport)

視口是一個為網(wǎng)頁提供繪圖區(qū)域的矩形。
你可以指定數(shù)個視口屬性彻坛,比如尺寸和初始縮放系數(shù)(initial scale)子巾。其中最重要的是視口寬度,它定義了網(wǎng)頁水平方向的可用像素總數(shù)(可用的CSS像素數(shù))小压。
多數(shù) Android 上的網(wǎng)頁瀏覽器(包括 Chrome)設置默認視口為一個大尺寸(被稱為"wide viewport mode"线梗,寬約 980px)。
也有許多瀏覽器默認會盡可能縮小以顯示完整的視口寬度(被稱為"overview mode")

// 是否支持viewport屬性怠益,默認值 false
// 頁面通過`<meta name="viewport" ... />`自適應手機屏幕
// 當值為true且viewport標簽不存在或未指定寬度時使用 wide viewport mode
settings.setUseWideViewPort(true);
// 是否使用overview mode加載頁面仪搔,默認值 false
// 當頁面寬度大于WebView寬度時,縮小使頁面寬度等于WebView寬度
settings.setLoadWithOverviewMode(true);

viewport 語法

<meta name="viewport"
      content="
          height = [pixel_value | "device-height"] ,
          width = [pixel_value | "device-width"] ,
          initial-scale = float_value ,
          minimum-scale = float_value ,
          maximum-scale = float_value ,
          user-scalable = ["yes" | "no"]
          " />

通過WebView設置初始縮放(initial-scale)

// 設置初始縮放百分比
// 0表示依賴于setUseWideViewPort和setLoadWithOverviewMode
// 100表示不縮放
web.setInitialScale(0)

2蜻牢、長按保存圖片或者撥打電話

一般瀏覽器都有長按保存圖片或者撥打圖片的功能烤咧,實現(xiàn)這個功能和WebView.HitTestResult這個類有關偏陪,這個類會將你觸摸網(wǎng)頁的地方的類型和其他信息反饋給你。

WebView.HitTestResult的常用方法:

  • HitTestResult.getExtra():獲取額外的信息煮嫌。
  • HitTestResult.getType():獲取所選中目標的類型笛谦,可以是圖片,超鏈接昌阿,郵件饥脑,電話等等。
    WebView.HitTestResult.UNKNOWN_TYPE //未知類型  
    WebView.HitTestResult.PHONE_TYPE //電話類型
    WebView.HitTestResult.EMAIL_TYPE //電子郵件類型
    WebView.HitTestResult.GEO_TYPE //地圖類型
    WebView.HitTestResult.SRC_ANCHOR_TYPE //超鏈接類型
    WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE //帶有鏈接的圖片類型
    WebView.HitTestResult.IMAGE_TYPE //單純的圖片類型
    WebView.HitTestResult.EDIT_TEXT_TYPE //選中的文字類型
    
  1. 給WebView設置長按監(jiān)聽事件懦冰;
  2. 獲取WebView長按時的WebView.HitTestResult的事件類型灶轰,如果是圖片,則做處理刷钢。
webView.setOnLongClickListener(new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View view) {
        WebView.HitTestResult result = ((WebView) view).getHitTestResult();
        if(result != null){
            switch (result.getType()){
                case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
                    String imgUrl = result.getExtra();
                    ...
                    return true;
                ...
            }
        }
        return false;
    }
});

3笋颤、與Javascript交互

啟用Javascript

// 是否支持Javascript,默認值false
settings.setJavaScriptEnabled(true); 

注入對象到Javascript

// 注入對象'jsobj'内地,在網(wǎng)頁中通過`jsobj.say(...)`調(diào)用
web.addJavascriptInterface(new JSObject(), "jsobj") 

在API17后支持白名單伴澄,只有添加了@JavascriptInterface注解的方法才會注入JS

public class JSObject {
    @JavascriptInterface
    public void say(String words) {
      // todo
    }
}

移除已注入Javascript的對象

web.removeJavascriptInterface("jsobj")

執(zhí)行JS表達式

// 彈出提示框
web.loadUrl("javascript:alert('hello')");
// 調(diào)用注入的jsobj.say方法
web.loadUrl("javascript:jsobj.say('hello')"); 

在API19后可異步執(zhí)行JS表達式,并通過回調(diào)返回值

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    vWeb.evaluateJavascript("111+222", new ValueCallback<String>() {
        @Override
        public void onReceiveValue(String value) {
            // value => "333"
        }
    });
}

4阱缓、全屏(Fullscreen)

  • 當H5請求全屏時秉版,會回調(diào) WebChromeClient.onShowCustomView 方法
  • 當H5退出全屏時,會回調(diào) WebChromeClient.onHideCustomView 方法
  1. manifest
    自己處理屏幕尺寸方向的變化(切換屏幕方向時不重建activity)
    WebView播放視頻需要開啟硬件加速
<activity
    android:name=".WebViewActivity"
    android:configChanges="orientation|screenSize"
    android:hardwareAccelerated="true"
    android:screenOrientation="portrait" />
  1. 處理全屏回調(diào)
CustomViewCallback mCallback;
View vCustom;

@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
    setFullscreen(true);
    vCustom = view;
    mCallback = callback;
    if (vCustom != null) {
        ViewGroup parent = (ViewGroup) vWeb.getParent();
        parent.addView(vCustom);
    }
}

@Override
public void onHideCustomView() {
    setFullscreen(false);
    if (vCustom != null) {
        ViewGroup parent = (ViewGroup) vWeb.getParent();
        parent.removeView(vCustom);
        vCustom = null;
    }
    if (mCallback != null) {
        mCallback.onCustomViewHidden();
        mCallback = null;
    } 
} 
  1. 設置全屏茬祷,切換屏幕方向
void setFullscreen(boolean fullscreen) { 
    if (fullscreen) {
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        vToolbar.setVisibility(View.GONE);
        vWeb.setVisibility(View.GONE);
    } else {
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        vToolbar.setVisibility(View.VISIBLE);
        vWeb.setVisibility(View.VISIBLE);
    }
    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    } else {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }
}

參考:
1清焕、Android WebView 詳解
2、WebView·開車指南
3祭犯、Android WebView 常用API參考手冊

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末秸妥,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子沃粗,更是在濱河造成了極大的恐慌粥惧,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件最盅,死亡現(xiàn)場離奇詭異突雪,居然都是意外死亡,警方通過查閱死者的電腦和手機涡贱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門咏删,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人问词,你說我怎么就攤上這事督函。” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵辰狡,是天一觀的道長锋叨。 經(jīng)常有香客問我,道長宛篇,這世上最難降的妖魔是什么娃磺? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮叫倍,結(jié)果婚禮上偷卧,老公的妹妹穿的比我還像新娘。我一直安慰自己段标,他們只是感情好涯冠,可當我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布炉奴。 她就那樣靜靜地躺著逼庞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瞻赶。 梳的紋絲不亂的頭發(fā)上赛糟,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天,我揣著相機與錄音砸逊,去河邊找鬼璧南。 笑死,一個胖子當著我的面吹牛师逸,可吹牛的內(nèi)容都是我干的司倚。 我是一名探鬼主播,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼篓像,長吁一口氣:“原來是場噩夢啊……” “哼动知!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起员辩,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤盒粮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后奠滑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丹皱,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年宋税,在試婚紗的時候發(fā)現(xiàn)自己被綠了摊崭。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡杰赛,死狀恐怖爽室,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤阔墩,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布嘿架,位于F島的核電站,受9級特大地震影響啸箫,放射性物質(zhì)發(fā)生泄漏耸彪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一忘苛、第九天 我趴在偏房一處隱蔽的房頂上張望蝉娜。 院中可真熱鬧,春花似錦扎唾、人聲如沸召川。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽荧呐。三九已至,卻和暖如春纸镊,著一層夾襖步出監(jiān)牢的瞬間倍阐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工逗威, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留峰搪,地道東北人。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓凯旭,卻偏偏與公主長得像概耻,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子罐呼,可洞房花燭夜當晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容