Recently I had to change the target SDK on one of my applications, but by doing that, I ran into some problems with the Android Canvas. In this application I use an animation which simulates an explosion. So, I tested my app and I noticed that everything was working OK, until I changed the target SDK from 12 to 19. When I changed the target, my image started to look like this:
instead of this:
My image was not rendered as it should have any more, and I didn’t know why or what happened. So after I spent a few hours of intense research I discovered that Android 3.0 introduced Hardware Acceleration. They added a new rendering pipeline in order to add some extra boost in performance. This means that some of the Android Canvas operations have been affected and they are not currently supported, even though they tried to support the most commonly used Android Canvas operations.
So, the unsupported operations are:
- clipPath
- clipRegion
- drawPicture
- drawPoints
- drawPosText
- drawTextOnPath
- drawVertices
Also some operations behave differently when hardware acceleration is enabled:
- Canvas operations
- Paint operations
- ComposeShader operations
Below I will give examples of operations that behave differently, but only for Android Canvas.
- clipRect: for this operation clip modes are ignored and 3D transforms do not apply for the clip rectangle.
- drawBitmapMesh: in this case the colors array is ignored
- drawLines: for this operation anti-aliasing is not supported
- setDrawFilter: even if this operation can be set, it is ignored
So my rendering problem was because of these changes, and the solution was to disable the hardware acceleration from my application. The Hardaware Acceleration can be disabled from AndroidManifest.xml by adding the hardwareAccelereted attribute and setting it to false like in the code below.
<application android:hardwareAccelerated="false" android:label="@string/app_name"> <activity android:name="MyActivity" android:label="@string/app_name" android:theme="@android:style/Theme.Black.NoTitleBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
Actually there are more ways to disable the hardware acceleration. Android gives us four ways to handle the acceleration. It can be enabled or disabled on the following elements:
- Application
- Window
- Activity
- View
So this means that we can enable the hardware acceleration for the entire application, and disable it for a certain activity. In my case I disabled it for the entire application because I didn’t need it, but if in your case you still need the hardware acceleration for other parts of your application (especially where you use animations), I suppose is good for you to know that you can keep it enabled where you need it to. Still, there is one place where the hardware acceleration cannot be disabled. It cannot be disabled for Window, but maybe you do not want to do that anyway, so it should not be a problem :)
But for more information you can read the post from Android Developers Blog.
To conclude, by disabling the hardware acceleration, the rendering problem was gone and my image now looks as it should. In my case, this solution helped me.
I hope this post was helpful for you as it was for me :)