Android 4.4
(API級(jí)別19)引入了基于Chromium
的新版WebView
们拙。 此更改升級(jí)了對(duì)HTML5
,CSS3
和JavaScript
的WebView
性能和標(biāo)準(zhǔn)支持,以匹配最新的Web
瀏覽器澜薄。 在Android 4.4
及更高版本上運(yùn)行時(shí)狗唉,任何使用WebView
的應(yīng)用程序都將繼承這些升級(jí)。
本文檔介紹了在將targetSdkVersion
設(shè)置為“19”或更高時(shí)應(yīng)注意的對(duì)WebView
的其他更改口注。
注意:如果您的
targetSdkVersion
設(shè)置為“18”或更低比伏,WebView
將以“怪癖模式”運(yùn)行,以避免下面描述的某些行為更改盡可能接近 - 同時(shí)仍為您的應(yīng)用程序提供性能和Web
標(biāo)準(zhǔn)升級(jí)疆导。 但請(qǐng)注意赁项,Android 4.4
上根本不支持單列和窄列布局以及默認(rèn)縮放級(jí)別,并且可能存在尚未識(shí)別的其他行為差異澈段,因此請(qǐng)務(wù)必在Android 4.4
或更高版本上測(cè)試您的應(yīng)用悠菜,即使 將targetSdkVersion
設(shè)置為“18”或更低。
為了幫助您解決在Android 4.4
中將應(yīng)用遷移到WebView
時(shí)可能遇到的任何問(wèn)題败富,您可以通過(guò)調(diào)用setWebContentsDebuggingEnabled()
在桌面上通過(guò)Chrome
啟用遠(yuǎn)程調(diào)試悔醋。WebView
中的這一新功能允許您在WebView
中運(yùn)行時(shí)檢查和分析Web內(nèi)容,腳本和網(wǎng)絡(luò)活動(dòng)兽叮。 有關(guān)更多信息芬骄,請(qǐng)參閱Android上的遠(yuǎn)程調(diào)試。
一鹦聪、用戶(hù)代理更改
如果您基于用戶(hù)代理向WebView
提供內(nèi)容账阻,則應(yīng)注意用戶(hù)代理字符串已略有更改,現(xiàn)在包括Chrome
版本:
Mozilla/5.0 (Linux; Android 4.4; Nexus 4 Build/KRT16H) AppleWebKit/537.36
(KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36
如果您需要檢索用戶(hù)代理但不需要為應(yīng)用程序存儲(chǔ)它或者不想實(shí)例化WebView
泽本,則應(yīng)使用靜態(tài)方法getDefaultUserAgent()
淘太。 但是,如果要在WebView
中覆蓋用戶(hù)代理字符串,則可能需要使用getUserAgentString()
蒲牧。
二撇贺、多線(xiàn)程和線(xiàn)程阻塞
如果從應(yīng)用程序的UI線(xiàn)程以外的任何線(xiàn)程調(diào)用WebView
上的方法,則可能導(dǎo)致意外結(jié)果冰抢。 例如松嘶,如果您的應(yīng)用程序使用多個(gè)線(xiàn)程,則可以使用runOnUiThread()
方法來(lái)確保您的代碼在UI線(xiàn)程上執(zhí)行:
runOnUiThread(new Runnable() {
@Override
public void run() {
// Code for WebView goes here
}
});
還要確保永遠(yuǎn)不會(huì)阻止UI線(xiàn)程挎扰。 某些應(yīng)用程序出現(xiàn)此錯(cuò)誤的情況是在等待JavaScript
回調(diào)時(shí)翠订。 例如,不要使用這樣的代碼:
// This code is BAD and will block the UI thread
webView.loadUrl("javascript:fn()");
while(result == null) {
Thread.sleep(100);
}
您可以使用新方法evaluateJavascript()
來(lái)異步運(yùn)行JavaScript
鼓鲁。
三蕴轨、自定義URL處理
在請(qǐng)求資源和解析使用自定義URL
方案的鏈接時(shí),新WebView
會(huì)應(yīng)用其他限制骇吭。 例如橙弱,如果實(shí)現(xiàn)了諸如shouldOverrideUrlLoading()
或shouldInterceptRequest()
之類(lèi)的回調(diào),則WebView
僅針對(duì)有效URL調(diào)用它們燥狰。
如果您使用自定義URL
方案或基本URL
棘脐,并注意到您的應(yīng)用程序接收的回調(diào)較少或未能在Android 4.4
上加載資源,請(qǐng)確保請(qǐng)求指定符合RFC 3986
的有效URL龙致。
例如蛀缝,新的WebView
可能不會(huì)為這樣的鏈接調(diào)用shouldOverrideUrlLoading()
方法:
<a href="showProfile">Show Profile</a>
用戶(hù)點(diǎn)擊此類(lèi)鏈接的結(jié)果可能會(huì)有所不同:
- 如果通過(guò)使用無(wú)效或空基
URL
調(diào)用loadData()
或loadDataWithBaseURL()
來(lái)加載頁(yè)面,則不會(huì)在頁(yè)面上收到此類(lèi)鏈接的shouldOverrideUrlLoading()
回調(diào)目代。
注意:使用
loadDataWithBaseURL()
并且基本URL
無(wú)效或設(shè)置為null時(shí)屈梁,要加載的內(nèi)容中的所有鏈接都必須是絕對(duì)的。
- 如果通過(guò)調(diào)用
loadUrl()
加載頁(yè)面或者使用loadDataWithBaseURL()
提供了有效的基本URL
榛了,那么您將在頁(yè)面上收到此類(lèi)鏈接的shouldOverrideUrlLoading()
回調(diào)在讶,但是您收到的URL將是絕對(duì)的,相對(duì)于 當(dāng)前頁(yè)面霜大。 例如构哺,您收到的網(wǎng)址為“http://www.example.com/showProfile”,而不僅僅是“showProfile”战坤。
如上所示曙强,您可以使用自定義方案,而不是在鏈接中使用簡(jiǎn)單字符串途茫,如下所示:
<a href="example-app:showProfile">Show Profile</a>
然后碟嘴,您可以在shouldOverrideUrlLoading()
方法中處理此URL
,如下所示:
// The URL scheme should be non-hierarchical (no trailing slashes)
private static final String APP_SCHEME = "example-app:";
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith(APP_SCHEME)) {
urlData = URLDecoder.decode(url.substring(APP_SCHEME.length()), "UTF-8");
respondToData(urlData);
return true;
}
return false;
}
如果您無(wú)法更改HTML
慈省,則可以使用loadDataWithBaseURL()
并設(shè)置包含自定義方案和有效主機(jī)的基本URL臀防,例如“example-app:// <valid_host_name> /”眠菇。 例如:
webView.loadDataWithBaseURL("example-app://example.co.uk/", HTML_DATA,
null, "UTF-8", null);
四边败、視口更改
不再支持視口目標(biāo)密度
以前袱衷,WebView
支持名為target-densitydpi
的視口屬性,以幫助網(wǎng)頁(yè)指定其預(yù)期的屏幕密度笑窜。 不再支持此屬性致燥,您應(yīng)該遷移到使用帶有圖像和CSS的標(biāo)準(zhǔn)解決方案,如WebView
中的Pixel-Perfect UI
中所述排截。
視口小時(shí)放大
以前嫌蚤,如果將視口寬度設(shè)置為小于或等于“320”的值,則將其設(shè)置為“device-width”断傲,如果將視口高度設(shè)置為小于或等于WebView
高度的值脱吱,則 將設(shè)置為“設(shè)備高度”。 但是认罩,在新WebView
中運(yùn)行時(shí)箱蝠,會(huì)粘貼寬度或高度值,WebView
會(huì)放大以填充屏幕寬度垦垂。
不支持多個(gè)視口標(biāo)記
以前宦搬,如果在網(wǎng)頁(yè)中包含多個(gè)視口標(biāo)記,則WebView
將合并所有標(biāo)記中的屬性劫拗。 在新的WebView
中间校,僅使用最后一個(gè)視口,而忽略所有其他視口页慷。
不推薦使用默認(rèn)縮放
用于獲取和設(shè)置頁(yè)面上的初始縮放級(jí)別的方法getDefaultZoom()
和setDefaultZoom()
不再受支持憔足,您應(yīng)該在網(wǎng)頁(yè)中定義適當(dāng)?shù)囊暱凇?/p>
注意:
Android 4.4
及更高版本不支持這些API
。 即使您的targetSdkVersion
設(shè)置為“18”或更低酒繁,這些API也無(wú)效滓彰。
有關(guān)如何在HTML中定義視口屬性的信息,請(qǐng)閱讀WebView
中的Pixel-Perfect UI欲逃。
如果無(wú)法在HTML
中設(shè)置視口的寬度找蜜,則應(yīng)調(diào)用setUseWideViewPort()
以確保為頁(yè)面提供更大的視口。 例如:
WebSettings settings = webView.getSettings();
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
五稳析、樣式變化
后臺(tái)CSS簡(jiǎn)寫(xiě)覆蓋后臺(tái)大小
Chrome
和其他瀏覽器已經(jīng)有一段時(shí)間的表現(xiàn)洗做,但是現(xiàn)在,如果您還指定了背景樣式彰居,WebView
也會(huì)覆蓋背景大小的CSS
設(shè)置诚纸。 例如,此處的大小將重置為默認(rèn)值:
.some-class {
background-size: contain;
background: url('images/image.png') no-repeat;
}
修復(fù)方法是簡(jiǎn)單地切換兩個(gè)屬性陈惰。
.some-class {
background: url('images/image.png') no-repeat;
background-size: contain;
}
大小是CSS像素而不是屏幕像素
以前畦徘,大小參數(shù)(如window.outerWidth
和window.outerHeight
)返回實(shí)際屏幕像素中的值。 在新的WebView
中,這些返回基于CSS
像素的值井辆。
對(duì)于尺寸調(diào)整元素或其他計(jì)算关筒,嘗試計(jì)算物理尺寸(以像素為單位)通常是不好的做法。 但是杯缺,如果您已禁用縮放并且初始比例設(shè)置為1.0蒸播,則可以使用window.devicePixelRatio
獲取比例,然后將CSS像素值乘以該值萍肆。 相反袍榆,您還可以創(chuàng)建JavaScript
綁定以從WebView
本身查詢(xún)像素大小。
有關(guān)更多信息塘揣,請(qǐng)參閱quirksmode.org包雀。
不再支持NARROW_COLUMNS和SINGLE_COLUMN
新WebView
不支持WebSettings.LayoutAlgorithm
的NARROW_COLUMNS
值。
注意:
Android 4.4
及更高版本不支持這些API
亲铡。 即使您的targetSdkVersion
設(shè)置為“18”或更低才写,這些API
也無(wú)效。
您可以通過(guò)以下方式處理此更改:
- 改變應(yīng)用程序的樣式:
如果您可以控制頁(yè)面上的HTML
和CSS
奴愉,您可能會(huì)發(fā)現(xiàn)更改內(nèi)容設(shè)計(jì)可能是最可靠的方法琅摩。 例如,對(duì)于引用許可證的屏幕锭硼,您可能希望在<pre>
標(biāo)記內(nèi)部包裝文本房资,您可以使用以下樣式執(zhí)行此操作:
<pre style="word-wrap: break-word; white-space: pre-wrap;">
如果您尚未為頁(yè)面定義視口屬性,這可能特別有用檀头。
- 使用新的
TEXT_AUTOSIZING
布局算法:
如果您使用窄列作為一種方法轰异,使移動(dòng)設(shè)備上的各種桌面網(wǎng)站更具可讀性,并且您無(wú)法更改HTML
內(nèi)容暑始,則新的TEXT_AUTOSIZING
算法可能是NARROW_COLUMNS
的合適替代方法搭独。
此外,新WebView
中也不支持先前已棄用的SINGLE_COLUMN
值廊镜。
六牙肝、在JavaScript中處理觸摸事件
如果您的網(wǎng)頁(yè)直接處理WebView
中的觸摸事件,請(qǐng)確保您還在處理touchcancel
事件嗤朴。 有幾種情況會(huì)調(diào)用touchcancel
配椭,如果沒(méi)有收到會(huì)導(dǎo)致問(wèn)題:
- 觸摸一個(gè)元素(因此調(diào)用
touchstart
和touchmove
)并滾動(dòng)頁(yè)面,從而引發(fā)touchcancel
雹姊。 - 觸摸一個(gè)元素(調(diào)用
touchstart
)但不調(diào)用event.preventDefault()
股缸,導(dǎo)致觸發(fā)touchcancel
(因此WebView
假定您不想使用觸摸事件)。