Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android系統教程 >> 安卓省電與加速 >> Android硬件加速

Android硬件加速

編輯:安卓省電與加速

概述


從Android 3.0開始(API L11),Android開始全面使用硬件加速來進行2D渲染,硬件加速是指Android中在View上進行繪制的圖形圖像都使用GPU來進行繪制,使用硬件加速,在大部分時候都讓繪制更加流暢,但付出的代價是需要消耗更多的內存資源。

硬件加速在API L14之上是默認開啟的,對於基本的View繪制,通過硬件加速可以增加繪圖的流程性,但是要注意的是,並不是所有的2D圖形繪制API都支持硬件加速。

通過開發者選項中的“強制進行GPU渲染”,用戶可以為全局打開硬件加速。在3.0 以上的Android中,系統已經對大部分動畫都進行了硬件加速。


控制硬件加速


由於硬件加速對某些2D繪圖API的不支持,所以Android系統提供了四種級別的控制方式。


Application級別


在應用的Android清單文件中,把下列屬性添加到元素中,來開啟整個應用程序的硬件加速,代碼如下所示:

android:hardwareAccelerated="true"


Activity級別


比整個App范圍稍小,我們可以在Activity范圍內進行控制,代碼如下所示:

android:hardwareAccelerated="true"


Window級別

針對單個的Window,Android同樣可以控制硬件加速,代碼如下所示:
getWindow().setFlags(
        WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
        WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

但是對Window來說,Android無法禁止硬件加速。



View級別


View級別是用的最多的控制硬件加速的級別,我們可以通過如下所示的代碼來禁止硬件加速:

setLayerType(View.LAYER_TYPE_SOFTWARE, null);

與Window級別相反,我們無法在View級別開啟硬件加速。


判斷View是否已開啟硬件加速


判斷View是否支持硬件加速一般有如下所示的兩種方法:


View.isHardwareAccelerated()
Canvas.isHardwareAccelerated()

盡量使用Canvas對象的判斷方法。

Android繪圖模式


相對於是否開啟硬件加速模式,Android的繪圖模式被分為兩種——基於軟件的繪圖模式與基於硬件的繪圖模式。

基於軟件的繪圖模式


基於軟件的繪圖模式在重繪View時,需要如下兩個過程:

Invalidate the hierarchyDraw the hierarchy

需要進行重繪時,系統發出invalidate()信號,並在View視圖樹中進行傳遞,計算需要重新繪制的區域,但是這種繪圖方式有兩個不足:

當我們只需要重繪視圖樹中的一個View時,視圖樹中的View都將進行重繪,而且遍歷視圖樹也浪費大量時間。例如一個ViewA在另一個ViewB之上,即使B沒有發生變化,重繪A的時候,B也會重繪。

這種方式隱藏了繪制中的bug,例如上面的例子中,由於ViewA、ViewB相互重疊,有需要重繪的the dirty region,那麼如果B忘記了進行重繪的邏輯,那麼A進行重繪的時候,就會將B重繪,也就是說使用錯誤的行為來得到了正確的現象。正是因為這個原因,開發者需要保證在View需要發生重繪時,調用正確的invalidate()方法。

基於硬件的繪圖模式


基於硬件的繪圖方式同樣使用invalidate()信號來進行重繪,但其繪制和渲染的方式不同。Android內部維護一個display list用於記錄視圖樹的顯示狀態。當收到invalidate()信號時,系統只需要更改需要重繪的視圖的display list,而其他未發生改變的視圖只需要使用原來的display list即可,整個過程分為三部分:

Invalidate the hierarchyRecord and update display listsDraw the display lists

使用這種方式,就可以避免軟件繪圖中第二點的bug。

例如,假設有一個包含了一個Button對象的ListView對象的LinearLayout布局,那麼LinearLayout布局的顯示列表如下:

1. DrawDisplayList(ListView);

2.DrawDisplayList(Button)

假設現在要改變ListView對象的不透明度,那麼在調用ListView對象的setAlpha(0.5f)方法時,顯示列表就包含了以下處理:

1.SaveLayerAlpha(0.5);

2.DrawDisplayList(ListView);

3. Restore;

4.DrawDisplayList(Button)


不支持硬件加速的繪圖方法


如果應用程序受到這些錯誤的功能或限制的影響,那麼能夠通過調用setLayerType(View.LAYER_TYPE_SOFTWARE, null)方法針對應用程序受到影響的部分來關閉硬件加速。

具體哪些方法不支持硬件加速可以參考Google開發者網站上的這篇文檔 http://developer.android.com/guide/topics/graphics/hardware-accel.html


View Layers


在所有的Android版本中,View都可以通過Canvas.saveLayer()方法來獲得離屏緩沖的能力,離屏緩沖區或層有多種用途,特別是在呈現復雜的動畫或使用組合效果時,能夠獲得更好的性能。例如,使用Canvas.saveLayer()可以實現淡入淡出的效果,先暫時把一個View對象渲染在一個層中,然後把它和不透明因子合成到屏幕上顯示。

從Android3.0(API Level 11)開始,用View.setLayerType()方法使用層的方式和時機會更多的控制。這個API需要兩個參數:一個是層的類型,另一個是可選的,用於描述層應該如何被合成的Paint對象。能夠使用這個Paint對象來進行顏色過濾、特殊的混合模式、或者層的透明度。View對象能夠使用以下三種層類型:


LAYER_TYPE_NONE:View對象用普通的方式來呈現,並且不是由屏幕外緩存來返回的。這種類型是默認的行為;LAYER_TYPE_HARDWARE:如果應用程序是硬件加速的,那麼該View對象被呈現在硬件的一個硬件紋理中。如果沒有被硬件加速,那麼這種層類型的行為與LAYER_TYPE_SOFTWARE相同。LAYER_TYPE_SOFTWARE:View對象會被呈現在軟件的一個位圖中。

使用哪種層的類型,依賴以下目標:

性能:使用硬件層類型,把View呈現到一個硬件紋理中。一旦該View對象被呈現到一個層中,那麼它的繪圖代碼直到調用該View對象的invalidate()方法時才會被執行。對於某些動畫,如alpha動畫,就能夠直接使用該層,這麼做對於GPU來說是非常高效的。 視覺效果:使用硬件或軟件層類型和一個Paint對象,能夠把一些特殊的視覺處理應用給一個View對象。例如,使用ColorMatrixColorFilter對象繪制一個黑白相間的View對象。 兼容性:使用軟件層類型會強制把一個View對象呈現在軟件中。如果View對象被硬件加速(例如,如果整個應用程序都被硬件加速)發生呈現問題,那麼使用軟件層類型來解決硬件呈現管道的限制是一個容易的方法。


View layers and animations


當應用層使用硬件加速的時候,手機顯示硬件可以讓動畫、顯示效果更加平滑。如果你的動畫效果不夠流暢,那麼就需要考慮在View層面上使用硬件加速來進行優化。在Android中,有些視圖操作使用硬件加速是非常高效的,因為這些操作不需要讓對象失效後重繪,例如:

1. alpha:改變層的透明度

2. x,y,translation,translation:改變層的位置

3. scaleX,scaleY:改變成的縮放

4. rotation,rotation,rotationY:改變3D空間中視圖的方向

5. pivotX,pivotY:改變層的變換控制點



對於以上屬性的動畫,在開啟硬件加速後將會得到非常高效的繪制,下面的代碼展示了如何高效的在3D空間中圍繞Y軸旋轉View對象,代碼如下所示:

view.setLayerType(View.LAYER_TYPE_HARDWARE,null);
ObjectAnimator.ofFloat(view,"rotationY",180).start();

但是由於硬件加速會消耗系統內存,因此強烈建議在動畫結束後取消硬件加速,代碼如下所示:

View.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotationY", 180);
animator.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        view.setLayerType(View.LAYER_TYPE_NONE, null);
    }
});
animator.start();


硬件加速的缺點


當我們使用硬件加速時,會消耗更多的內存(將近4倍),如果分給應用的內存沒有這麼多,那麼就會從系統剩於內存中進行劃分,因此,硬件加速不適用於系統的核心進程。好的應用,應該在硬件加速(GPU)與軟件繪制(CPU)中找到平衡點。

另外,需要注意的是,App中進行UI渲染是無法使用並發的,多核心無法帶來顯示上的性能提升。同時,分辨率也是影響流暢度的一個非常重要的方面,為了能夠在更高的分辨率上進行流暢的繪制效果,那麼就需要使用更加強大的GPU進行渲染。















  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved