WebView簡介(加速載入篇)

2021-09-22 07:37:54 字數 3220 閱讀 3987

從android 3.0開始,android的2d渲染管線可以更好的支援硬體加速。硬體加速使用gpu進行view上的繪製操作。

硬體加速可以在一下四個級別開啟或關閉:

activity

window

view

如果您需要更小粒度的控制,可以使用如下**開啟某個window的硬體加速:

getwindow().setflags(    windowmanager.layoutparams.flag_hardware_accelerated,    windowmanager.layoutparams.flag_hardware_accelerated);
注:目前還不能在window級別關閉硬體加速。

您可以在執行時用以下的**關閉單個view的硬體加速:

myview.setlayertype(view.layer_type_software, null);
注:您不能在view級別開啟硬體加速

很明顯,硬體加速能夠帶來效能提公升,android為什麼要弄出這麼多級別的控制,而不是預設就是全部硬體加速呢?原因是並非所有的2d繪圖操作支援硬體加速,如果您的程式中使用了自定義檢視或者繪圖呼叫,程式可能會工作不正常。如果您的程式中只是用了標準的檢視和drawable,放心大膽的開啟硬體加速吧!具體是哪些繪圖操作不支援硬體加速呢?以下是已知不支援硬體加速的繪圖操作:

paint

另外還有一些繪圖操作,開啟和不開啟硬體加速,效果不一樣:

canvas

paint

composeshader

如果應用程式受到這些影響,您可以在受影響的部分呼叫setlayertype(view.layer_type_software, null),這樣在其它地方仍然可以享受硬體加速帶來的好處

開啟硬體加速後,android框架將採用新的繪製模型。基於軟體的繪製模型和基於硬體的繪製模型有和不同呢?

基於軟體的繪製模型

在軟體繪製模型下,檢視按照如下兩個步驟繪製:

1. invalidate the hierarchy(注:hierarchy怎麼翻譯?)

2. draw the hierarchy

應用程式呼叫invalidate()更新ui的某一部分,失效(invalidation)訊息將會在整個檢視層中傳遞,計算每個需要重繪的區域(即髒區域)。然後android系統將會重繪所有和髒區域有交集的view。很明顯,這種繪圖模式存在缺點:

1. 每個繪製操作中會執行不必要的**。比如如果應用程式呼叫invalidate()重繪button,而button又位於另乙個view之上,即使該view沒有變化,也會進行重繪。

2. 可能會掩蓋一些應用程式的bug。因為android系統會重繪與髒區域有交集的view,所以view的內容可能會在沒有呼叫invalidate()的情況下重繪。這可能會導致乙個view依賴於其它view的失效才得到正確的行為。

基於硬體的繪製模型

android系統仍然使用invalidate()和draw()來繪製view,但在處理繪製上有所不同。android系統記錄繪製命令到顯示列表,而不是立即執行繪製命令。另乙個優化就是android系統只需記錄和更新標記為臟(通過invalidate())的view。新的繪製模型包含三個步驟:

1. invalidate the hierarchy

2. 記錄和更新顯示列表

3. 繪製顯示列表

layer_type_software

無論硬體加速是否開啟,都會有一張bitmap(software layer),並在上面對webview進行軟渲染。

好處:在進行動畫,使用software可以只畫一次view樹,很省。

什麼時候不要用:

view樹經常更新時不要用。尤其是在硬體加速開啟時,每次更新消耗的時間更多。因為渲染完這張bitmap後還需要再把這張bitmap渲染到hardware layer上面去。

layer_type_hardware

硬體加速關閉時,作用同software。

硬體加速開啟時會在fbo(framebuffer object)上面做渲染,在進行動畫時,view樹也只需要畫一次。

兩者區別

1、乙個是渲染到bitmap,乙個是渲染到fb上。

2、hardware可能會有一些操作不支援。

兩者相同:

都是開了乙個buffer,把view畫到這個buffer上面去。

layer_type_none

這個就比較簡單了,不為這個view樹建立單獨的layer

ps:glsu***ceview和webview預設layertype都是none。

glsu***ceview:

給glsu***ceview設定為software或者hardware後,發現什麼也畫不出來了。得出結論:glsu***ceview的layer type只能是none

webview:

以前使用webview時碰到過乙個問題,如果在webview上面使用animation,webview的繪畫區域不動。當時的解決方案是在進行動畫之前對webview進行截圖(drawingcache)。按上面的道理試了一下,設定乙個hardware或者software的layer就ok了。

現在又碰到了另外乙個問題,開啟硬體加速後,在一些機器上面(我的是3.2)webview有時會出現某一塊區域白屏的問題。預設的layer type是none,改為hardware也不行,設定為software就解決了。當然關閉硬體加速也好了,可是那樣的話程式整體就比較慢了。所以最終方案是整體硬體加速,出問題的webview設定software

補充於2012.4.21:

加上這一句,可以讓3d的繪製更快一些:getholder().settype(su***ceholder.su***ce_type_hardware);

補充於2012.4.22

當我們在使用webview時,如果載入的網友比較大,這載入速度將非常慢。

現總結幾種加速webview載入的方法

1、提高渲染的優先順序

webview.getsettings().setrenderpriority(renderpriority.high);

2、使用webview.getsettings().setblocknetworkimage,把載入放在最後來載入渲染。參照示例1.

3,使用硬體加速,該功能在android 3.0 (api level 11)才加入。具體參照:

WebView簡介(加速載入篇)

當我們在使用webview時,如果載入的比較大,這載入速度將非常慢。現總結幾種加速webview載入的方法 1 提高渲染的優先順序 webview.getsettings setrenderpriority renderpriority.high 2 使用 webview.getsettings s...

WebView簡介(加速載入篇)

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!當我們在使用webview時,如果載入的比較大,這載入速度將非常慢。現總結幾種加速webview載入的方法 1 提高渲染的優先順序 webview.getsettings setrenderpriority renderpriority.high ...

webview載入優化

override public webresourceresponse shouldinterceptrequest webview view,string url else if url.contains 20.b7e931615e2f93316749.js else if url.contain...