如何從軟硬件層面提升 Android 動畫性能?

若是有人問如何解決動畫性能不佳的問題,Dan Lew Codes 總會反問:你是否使用了硬件層?

動畫放映過程中每幀畫面可能都要重繪。如果使用視圖層,,渲染過的視圖可以存入離屏緩存以待將來重用,而無需每幀重繪。

此外,硬件層緩存與 GPU 中,這使得動畫放映中的某些操作更加快速。簡單的轉換(平移,旋轉,縮放,開端)可通過硬件層快速渲染。由於許多動畫只是這些轉換的組合,使用硬件層可大大提高動畫性能。

Usage

應用

硬件層 API 十分簡單:使用 View.setLayerType()即可。硬件層設定只能暫時使用,因爲它們並非沒有代價(下文會有更多相關介紹)。基本過程如下:

  1. 動畫過程中,對每個需要緩存的視圖調用View.setLayerType(View.LAYERTYPEHARDWARE, null)
  2. 運行動畫
  3. 動畫結束時,使用 View.setLayerType(View.LAYERTYPENONE, null)清除緩存。

以下爲上述過程的具體實施:

// Set the layer type to hardware                   
myView.setLayerType(View.LAYER_TYPE_HARDWARE, null); 

// Setup the animation 
ObjectAnimator animator = ObjectAnimator.ofFloat(myView, View.TRANSLATION_X, 150); 

// Add a listener that does cleanup 
animator.addListener(new AnimatorListenerAdapter() {   
  @Override  
  public void onAnimationEnd(Animatoranimation){
    myView.setLayerType(View.LAYER_TYPE_NONE, null);
  } 
}); 

// Start the animation 
animator.start();  

如果你使用 minSdkVersion 16以上版本與ViewPropertyAnimator,可用簡便的withLayer()代替上述方法。

myView.animate()     
.translationX(150)  
.withLayer()   
.start();

這樣做之後,動畫變得很流暢!

警告

…你也知道,事實並非如此簡單。

硬件層在提高動畫性能方面能力優異。然而,如果使用不當,也可能弊大於利。千萬不要盲目使用硬件層!

首先,在很多情況下,硬件層實際進行的操作可能不止於簡單的視圖渲染。緩存硬件層的耗時不少,因爲第一步其實包含兩個過程:一、把視圖渲染進 GPU 的層中。二、GPU 將該層渲染爲視窗。如果該視圖渲染比較簡單(例如色彩單一),硬件層可能在初始過程中導致非必要的內存開銷。

第二,對於所有緩存,都存在緩存失效的可能。在動畫過程中,如果有人調用了 View.invalidate(),則硬件層不得不再次渲染。經常這樣做事實上比沒有硬件層還要糟糕,因爲(如前所述)硬件層在初始化緩存時會增加內存開銷。如果經常性地二次緩存硬件層,勢必影響動畫性能!

由於動畫經常包括多個移動部件,該問題極易發生。假定你在設置一個具有三個移動部件的動畫。

父 ViewGroup

-->子視圖1(向左平移)-->子視圖2(向右平移)-->子視圖3(向上平移)

假使你在父ViewGroup 配置了單獨的硬件層,會造成緩存持續失效,這是因爲ViewGroup(作爲整體)由於其子視圖的變化而持續改變。然而,每個獨立的視圖來說,只是在平移而已。因此,最好爲每個子視圖(而非父容器)配置硬件層。重申一點:爲多個視圖配置硬件層,可保證其在動畫過程中不失效。

“展示硬件層更新”是用於追蹤此類問題的好工具。每當視圖渲染硬件層時,它會使視圖閃現綠色。在動畫開始時(即硬件層初始渲染)時它只會閃光一次。然而,如果你的視圖在整個動畫過程中一直呈現綠色,說明你遇到緩存失效問題了。

第三,硬件層會佔用GPU存儲空間,你當然不想出現內存泄露。所以,你只應在必要時使用硬件層,比如動畫展示過程。

綜上所述-並不存在硬性規則。安卓渲染系統是複雜的,經常讓我吃驚。對於所有性能問題,檢測是關鍵。“GPU渲染分析”和“硬件層更新展示”設置能用於有效判斷硬件層的作用好壞。

舉例

我寫了一個例子以演示硬件層的基本應用。你可以在此處得到源碼

以下是啓用GPU渲染分析設置後,應用在GalaxyNexus(一個又老又慢的設備)上的運行結果

如何從軟硬件層面提升 Android 動畫性能? 技術分享 第1張

沒有硬件層,如此簡單的動畫也非常糟糕,經常性地位於綠線之上意味着應用性能簡直是一團亂麻。相反,使用了硬件層的版本則一直在綠線之下-太棒了!

第三個案例展示了動畫中使用硬件層但是緩存失效造成的危害。因爲誤使硬件層,許多性能提升也毀於一旦。(奇怪之處在於-如果它緩存失效,爲什麼並不像沒有使用硬件層那樣慢呢?雖然我也無法完全理解箇中緣由,但顯然,即使它每一步都要重繪,硬件層還是帶來一些有利的優化。不過,最好還是正確地使用硬件層。)

這個故事要的主旨是:硬件層的確有利於提升動畫性能,但必須正確使用之。

軟件層優化

從硬件層面進行了優化,那麼如何從軟件層面進行快速定位及優化呢?

使用OneAPM可以快速定位分析UI性能,Mobile Insight的卡頓可以直觀地展示這些信息。如何從軟硬件層面提升 Android 動畫性能? 技術分享 第2張可以分析繪製APP卡頓趨勢圖,精確定位每1秒內的繪圖刷新信號中斷的次數,從多維度分析卡頓現象,如APP版本、操作系統版本的分佈情況等。如何從軟硬件層面提升 Android 動畫性能? 技術分享 第3張卡頓詳情列表展示:訪問時間,發生卡頓時的流暢度,耗時,發生卡頓時的設備信息,APP版本,操作系統及版本,CPU信息通過分析該頁面信息可以清楚瞭解到卡頓來源,以便針對性快速優化。如何從軟硬件層面提升 Android 動畫性能? 技術分享 第4張

動畫卡頓原因

動畫卡頓的原因大概有這樣三種,這些因素將直接影響動畫的性能,導致卡頓。即:

  1. 手勢滑動速度
  2. 幀率
  3. 觸摸事件響應的速度

手勢滑動、幀率是跟各種手機設備有直接的關係,各種各樣的硬件設備會表現出不一樣的性能,如果從這個方面入手考慮優化,就十分需要 OneAPM Mobile Insight 這樣的從多維度來分析性能的一款工具。

原文地址:http://blog.danlew.net/2015/10/20/using-hardware-layers-to-improve-animation-performance/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章