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:
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:
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 🙂
Search In Blog
Want to donate?
Recent Posts: My Android Solutions
If you ever wondered how to read and parse a simple JSON file stored in the assets directory of your Android project, here is a way to do it.
In this tutorial I will create a simple Sectioned RecyclerView that will show 2 sections and a few items in each section and how to move an item from one section to another. Note: For RecyclerView I used AndroidX imports and not android.support.v7.widget.RecyclerView! Setup We need to import the recycler view from AndroidX. The build.gradle…
Recently, I had to add a perfect square CardView and I wanted to achieve this without hardcoding its width and height. I happily discovered the power of ConstraintLayout and this is how I managed to create a perfect square which should work on every dimension. In my project I created a RecyclerView with 2 columns,…