在Android 4.4中遷移到WebView(四)

Android 4.4(API級(jí)別19)引入了基于Chromium的新版WebView们拙。 此更改升級(jí)了對(duì)HTML5CSS3JavaScriptWebView性能和標(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.outerWidthwindow.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.LayoutAlgorithmNARROW_COLUMNS值。

注意:Android 4.4及更高版本不支持這些API亲铡。 即使您的targetSdkVersion設(shè)置為“18”或更低才写,這些API也無(wú)效。

您可以通過(guò)以下方式處理此更改:

  • 改變應(yīng)用程序的樣式:
    如果您可以控制頁(yè)面上的HTMLCSS奴愉,您可能會(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)用touchstarttouchmove)并滾動(dòng)頁(yè)面,從而引發(fā)touchcancel雹姊。
  • 觸摸一個(gè)元素(調(diào)用touchstart)但不調(diào)用event.preventDefault()股缸,導(dǎo)致觸發(fā)touchcancel(因此WebView假定您不想使用觸摸事件)。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末吱雏,一起剝皮案震驚了整個(gè)濱河市敦姻,隨后出現(xiàn)的幾起案子瘾境,更是在濱河造成了極大的恐慌,老刑警劉巖镰惦,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件迷守,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡陨献,警方通過(guò)查閱死者的電腦和手機(jī)盒犹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)懂更,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)眨业,“玉大人,你說(shuō)我怎么就攤上這事沮协×浼瘢” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵慷暂,是天一觀的道長(zhǎng)聘殖。 經(jīng)常有香客問(wèn)我,道長(zhǎng)行瑞,這世上最難降的妖魔是什么奸腺? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮血久,結(jié)果婚禮上突照,老公的妹妹穿的比我還像新娘。我一直安慰自己氧吐,他們只是感情好讹蘑,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著筑舅,像睡著了一般座慰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上翠拣,一...
    開(kāi)封第一講書(shū)人閱讀 51,301評(píng)論 1 301
  • 那天版仔,我揣著相機(jī)與錄音,去河邊找鬼误墓。 笑死蛮粮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的优烧。 我是一名探鬼主播蝉揍,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼畦娄!你這毒婦竟也來(lái)了又沾?” 一聲冷哼從身側(cè)響起弊仪,我...
    開(kāi)封第一講書(shū)人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎杖刷,沒(méi)想到半個(gè)月后励饵,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡滑燃,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年役听,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片表窘。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡典予,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出乐严,到底是詐尸還是另有隱情瘤袖,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布昂验,位于F島的核電站捂敌,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏既琴。R本人自食惡果不足惜占婉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望甫恩。 院中可真熱鬧逆济,春花似錦、人聲如沸填物。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)滞磺。三九已至升薯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間击困,已是汗流浹背涎劈。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留阅茶,地道東北人蛛枚。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像脸哀,于是被迫代替她去往敵國(guó)和親蹦浦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

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