Beginning in Android 3.0 (API level 11), the Android 2D rendering pipeline supports hardware acceleration, meaning that all drawing operations that are performed on a View
's canvas use the GPU. Because of the increased resources required to enable hardware acceleration, your app will consume more RAM.
You can control hardware acceleration at the following levels:
- 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);
-
Note: You currently cannot disable hardware acceleration at the window level.
- View:
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
There are two different ways to check whether the application is hardware accelerated:
View.isHardwareAccelerated()
returnstrue
if theView
is attached to a hardware accelerated window.Canvas.isHardwareAccelerated()
returnstrue
if theCanvas
is hardware accelerated
If you must do this check in your drawing code, use Canvas.isHardwareAccelerated()
instead ofView.isHardwareAccelerated()
when possible. When a view is attached to a hardware accelerated window, it can still be drawn using a non-hardware accelerated Canvas. This happens, for instance, when drawing a view into a bitmap for caching purposes.
In the software drawing model, views are drawn with the following two steps:
- Invalidate the hierarchy
- Draw the hierarchy
The Android system still uses invalidate()
and draw()
to request screen updates and to render views, but handles the actual drawing differently. Instead of executing the drawing commands immediately, the Android system records them inside display lists, which contain the output of the view hierarchy’s drawing code. Another optimization is that the Android system only needs to record and update display lists for views marked dirty by an invalidate()
call. Views that have not been invalidated can be redrawn simply by re-issuing the previously recorded display list. The new drawing model contains three stages:
- Invalidate the hierarchy
- Record and update display lists
- Draw the display lists
Beginning in Android 3.0 (API level 11), you have more control on how and when to use layers with theView.setLayerType()
method. This API takes two parameters: the type of layer you want to use and an optional Paint
object that describes how the layer should be composited. You can use the Paint
parameter to apply color filters, special blending modes, or opacity to a layer. A view can use one of three layer types:
LAYER_TYPE_NONE
: The view is rendered normally and is not backed by an off-screen buffer. This is the default behavior.LAYER_TYPE_HARDWARE
: The view is rendered in hardware into a hardware texture if the application is hardware accelerated. If the application is not hardware accelerated, this layer type behaves the same asLAYER_TYPE_SOFTWARE
.LAYER_TYPE_SOFTWARE
: The view is rendered in software into a bitmap.
Calling the setter for any of these properties results in optimal invalidation and no redrawing of the targeted view:
alpha
: Changes the layer's opacityx
,y
,translationX
,translationY
: Changes the layer's positionscaleX
,scaleY
: Changes the layer's sizerotation
,rotationX
,rotationY
: Changes the layer's orientation in 3D spacepivotX
,pivotY
: Changes the layer's transformations origin
>Switching to hardware accelerated 2D graphics can instantly increase performance, but you should still design your application to use the GPU effectively by following these recommendations:
Reduce the number of views in your application
Paint
or a new
Path
every time a rendering method is invoked. This forces the garbage collector to run more often and also bypasses caches and optimizations in the hardware pipeline.
setAlpha()
,
AlphaAnimation
, or
ObjectAnimator
, it is rendered in an off-screen buffer which doubles the required fill-rate. When applying alpha on very large views, consider setting the view's layer type to
LAYER_TYPE_HARDWARE
.