硬件加速
Android 3.0 (API level 11)開始,Android 2D渲染管道支持硬件加速绩衷。API level >=14的Android系統(tǒng)默認開啟硬件加速蹦魔。由于硬件加速并不支持所有的2D繪制操作,所以開啟硬件加速咳燕,可能會導(dǎo)致自定義view中部分元素看不到勿决,程序拋出異常,或者錯誤的像素渲染等問題招盲。
開啟/關(guān)閉硬件加速
- Application
<application android:hardwareAccelerated="true" ...>
- Activity
<application android:hardwareAccelerated="true">
<activity ... />
<activity android:hardwareAccelerated="false" />
</application>
- Window 級別只能開啟硬件加速
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
- View 關(guān)閉硬件加速
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
View硬件加速的判斷
兩個方法:
你必須在你繪制代碼(drawing code)內(nèi)檢測低缩,使用前者而不是后者,因為有可能View雖然依附于一個硬件加速的窗口曹货,但它依然可以在一個沒有硬件加速的Canvas上繪制咆繁,列如:為了緩存的目的把view繪制到一個bitmap上。
Android 軟加速/硬加速 繪制模式
基于軟件的繪制模式
繪制步驟:無效從下到上的View顶籽,然后重新繪制玩般。
問題:
- 沒有改變的大量上層的View需要重新繪制。
- Android重繪view的過程礼饱,有可能沒有繪制發(fā)生改變的view坏为,此時你只能依賴其他view包含恰好的重繪行為。
硬件加速的繪制模式
繪制步驟:
- 無效從下到上的View
- 記錄和更新顯示列表(display lists)
- 繪制顯示列表
優(yōu)點: 使用display lists能有針對性的更新改變的View
不支持的繪制操作
Canvas Scaling
View Layers
Off-screen buffers
- a view's drawing cache
- [Canvas.saveLayer()](https://developer.android.com/reference/android/graphics/Canvas.html#saveLayer(android.graphics.RectF, android.graphics.Paint))
所有的Android版本都支持對Off-screen buffers進行渲染镊绪。
你會獲得更好的性能匀伏,當做復(fù)雜view的動畫或者應(yīng)用合成效果時。列如镰吆,當你實現(xiàn)淡出效果時帘撰,你可以使用Canvas.saveLayer(),暫存渲染的view到layer中万皿,然后用透明度合成摧找,使它返回屏幕達到淡出效果核行。
[View.setLayerType()](https://developer.android.com/reference/android/view/View.html#setLayerType(int, android.graphics.Paint))
- LAYER_TYPE_NONE 不使用 off-screen buffer 【默認】
- LAYER_TYPE_HARDWARE
- LAYER_TYPE_SOFTWARE
選擇技巧
- Performance: 使用硬件加速時,一旦一個view渲染進如layer中蹬耘,只有調(diào)用invalidate()是繪制的代碼才會被執(zhí)行芝雪。一些動畫,列如透明度動畫综苔,可以直接用于layer中惩系,這使用GPU去執(zhí)行是非常高效的。
- Compatibility: Use a software layer type to force a view to be rendered in software.
View layers and animations
如果你在你的應(yīng)用中跑的動畫沒有達到如筛,你想要的流程結(jié)果堡牡,你可以考慮啟動硬件加速。 以下的屬性杨刨,使用合成來作用于layer晤柄,使用的是優(yōu)化的invalidation及不需要重繪目標view,過程更高效妖胀。
- alpha: Changes the layer's opacity
- x, y, translationX, translationY: Changes the layer's position
- scaleX, scaleY: Changes the layer's size
- rotation, rotationX, rotationY: Changes the layer's orientation in 3D space
- pivotX, pivotY: Changes the layer's transformations origin
demo:
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();
提示和技巧
- 減少view的數(shù)量
- 避免過度繪制
A good rule of thumb with current hardware is to not draw more than 2.5 times the number of pixels on screen per frame (transparent pixels in a bitmap count!). - 不創(chuàng)建渲染類在繪制代碼中:如在onDraw中 new Paint 或者 Path芥颈。
- 不頻繁的改變形狀
Complex shapes, paths, and circles for instance, are rendered using texture masks. Every time you create or modify a path, the hardware pipeline creates a new mask, which can be expensive. - 不頻繁的修改bitmap
- 謹慎使用alpha,當應(yīng)用alpha屬性到很大的views時赚抡,考慮使用 LAYER_TYPE_HARDWARE爬坑。
.