Android中的硬體加速
從Android 3.0開始,Android的2D渲染管線可以更好的支援硬體加速。硬體加速使用GPU進行View上的繪製操作。
硬體加速可以在一下四個級別開啟或關閉:
- Application
- Activity
- Window
- View
Application級別
往您的應用程式AndroidManifest.xml檔案為application標籤新增如下的屬性即可為整個應用程式開啟硬體加速:
<application android:hardwareAccelerated="true" ...>
Activity級別
您還可以控制每個activity是否開啟硬體加速,只需在activity元素中新增android:hardwareAccelerated
<application android:hardwareAccelerated="true"> <activity ... /> <activity android:hardwareAccelerated="false" /></application>
Window級別
如果您需要更小粒度的控制,可以使用如下程式碼開啟某個window的硬體加速:
getWindow().setFlags( WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
注:目前還不能在window級別關閉硬體加速。
View級別
您可以在執行時用以下的程式碼關閉單個view的硬體加速:
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
注:您不能在view級別開啟硬體加速
為什麼需要這麼多級別的控制?
很明顯,硬體加速能夠帶來效能提升,android為什麼要弄出這麼多級別的控制,而不是預設就是全部硬體加速呢?原因是並非所有的2D繪圖操作支援硬體加速,如果您的程式中使用了自定義檢視或者繪圖呼叫,程式可能會工作不正常。如果您的程式中只是用了標準的檢視和Drawable,放心大膽的開啟硬體加速吧!具體是哪些繪圖操作不支援硬體加速呢?以下是已知不支援硬體加速的繪圖操作:
Android的繪製模型
開啟硬體加速後,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. 繪製顯示列表