1.流暢度定義
16.67ms刷新一幀即一個Vsync
2.界面機制
code或xml編寫界面佈局,轉成DisplayList,由屏幕展示
3.案例分析
as GPU Render:分析是否掉幀
Overdraw 像素點多次繪製,綠色是1次,藍色是2次,紅色是3次以上
systrace性能分析,耗時分析
traceview 具體分析每個線程,每個函數耗時
4.總結
overdraw:
原因:1.繪製未展示的UI;2.重複繪製相同ui或已存在的ui;
優化:
1.可以通過canvas.clipRect()來幫助系統識別那些可見的區域。這個方法可以指定一塊矩形區域,只有在這個區域內纔會被繪製,其他的區域會被忽視,即局部繪製的思想;clipRect方法還可以幫助節約CPU與GPU資源,在clipRect區域之外的繪製指令都不會被執行,那些部分內容在矩形區域內的組件,仍然會得到繪製。
2.使用canvas.quickreject()來判斷是否沒和某個矩形相交。若判斷與矩形相交,則可跳過相交的區域,從而減少過度繪製。
3.移除不需要的backgrand(默認windows的背景色):可以在代碼中getWndow.setBackgrandDrawable(null) 或xml中設置爲null如style中
<item name="android:windowBackground">@null</item>
4.透明度渲染
setLayerType設置硬件加速,可以加速渲染
使用View layers(硬件層),我們可以將view渲染入一個非屏幕區域緩衝區(off-screen buffer,前面透明度部分提到過),並且根據我們的需求來操控它。這個功能主要是針對動畫,因爲它能讓複雜的動畫效果更加的流暢。而不使用硬件層的話,View會在動畫屬性(例如coordinate, scale, alpha值等)改變之後進行一次刷新。而對於相對複雜的view,這一次刷新又會連帶它所有的子view進行刷新,並各自重新繪製,相當的耗費性能。使用View layers,通過調用硬件層,GPU直接爲我們的view創建一個結構,並且不會造成view的刷新。而我們可以在避免刷新的情況下對這個結構進行進行很多種的操作,例如x/y位置變換,旋轉,透明度等等。總之,這意味着我們可以對一個讓一個複雜view執行動畫的同時,又不會刷新!這會讓動畫看起來更加的流暢
// Using the Object animator
view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, View.TRANSLATION_X, 20f);
objectAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
view.setLayerType(View.LAYER_TYPE_NONE, null);
}
});
objectAnimator.start();
// Using the Property animator
view.animate().translationX(20f).withLayer().start();
有幾點要牢記在心:
- 回收 – 硬件層會佔用GPU中的一塊內存。只在必要的時候使用他們,比如動畫,並且事後注意回收。例如在上面ObjectAnimator的例子中,我們增加了一個動畫結束監聽以便在動畫結束後可以移除硬件層。而在Property animator的例子中,我們使用了withLayers(),這會在動畫開始時候自動創建硬件層並且在結束的時候自動移除。
- 如果你在調用了硬件View layers後改變了View,那麼會造成硬件硬件層的刷新並且再次重頭渲染一遍view到非屏幕區域緩存中。這種情況通常發生在我們使用了硬件層暫時還不支持的屬性(目前爲止,硬件層只針對以下幾種屬性做了優化:otation、scale、x/y、translation、pivot和alpha)。例如,如果你另一個view執行動畫,並且使用硬件層,在屏幕滑動他們的同時改變他的背景顏色,這就會造成硬件層的持續刷新。而以硬件層的持續刷新所造成的性能消耗來說,可能讓它在這裏的使用變得並不那麼值。
5.繪製陰影的時候,在hasOverlappingRender回調中返回false。
在android的View裏有透明度的屬性,當設置透明度setAlpha的時候,android裏默認會把當前view繪製到offscreen buffer中,然後再顯示出來。 這個offscreen buffer 可以理解爲一個臨時緩衝區,把當前View放進來並做透明度的轉化,然後在顯示到屏幕上。這個過程是消耗資源的,所以應該儘量避免這個過程。
當繼承了hasOverlappingRendering()方法返回false後,android會自動進行合理的優化,避免使用offscreen buffer。
需要注意的是,當調用forceHasOverlappingRendering(boolean b)後這個方法就會被忽略。
6.減少層級減少嵌套,用輕量級的控件實現ui
————————————————
版權聲明:本文爲CSDN博主「星辰旋風」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/xingchenxuanfeng/article/details/56488045
https://www.jianshu.com/p/cbdaeb1bede5