This article was orginally posted on Medium on March 21st, 2016. You can find it here.
If you haven’t heard already, Android now has VectorDrawableCompat, hurrah!
There have been a few articles on how to use it already:
They both do a good job explaining how to implement VectorDrawableCompat into your project. So I’m just going to talk about a few things I ran into and how it’s going to affect an app on the playstore.
One thing I do want to make clear, even if you’re not going to be using VectorDrawableCompat in your project, is this (paraphrasing Chris Banes):
If you do not use the compat vector functionality yourself, you still need to make changes to your code as AppCompat needs it.
Please be aware of this and go see his post on how to code for this. It’s just a simple copy/paste job into your gradle file.
It’s bigger than I thought (that’s what she said)
When I first created the Fantasy Football Fix app back in December 2015 I was keen on implementing VectorDrawables. The issue I ran into was this; I wanted as many images as possible to be vector format, for as many densities as possible, from Lollipop onwards. This was a struggle because at the time there were only some third party libraries, with some being deprecated. With this in mind, I wanted to wait for an official Google implementation. While I was waiting I had to do the following:
Why all the folders? I needed vectors for any devices that were on Lollipop+ but I also needed folders for the devices that weren’t and for each density I was choosing to support. It was a pain, but my love of crisp images was not enough to drive me away!
All in all the app weighed in at 10.5MB (with proguard enabled). It was bigger than I first thought it would be, but I have a few libraries in there as well. It wasn’t too outrageous as far as I was concerned. The app was released successfully on the playstore and life went on. Until now.
Your bum no longer looks big in that
This past weekend I decided to update the support libraries and try my hand at implementing VectorDrawableCompat to see how much weight the app could lose. Following along with Chris Banes’s article I made changes to my gradle file. I then proceeded to remove all the unnecessary drawable folders. After, it looked like this:
A lot better right? Because i’m using vectors for a majority of my images they can all be placed in the drawable folder. What’s leftover is a few things that I hope to move to vector format once I can get the SVGs to convert them.
Next I searched my ImageViews in XML for the android:src
attribute and change it to app:srcCompat
. Make sure you get them all if you decide to go all out like me. If you don’t, then you’ll likely get a crash on devices pre-Lollipop. The last thing to do was scan my code for references to setting drawables e.g. in a custom view. For example my custom PlayerView had this code at the bottom to factor in deprecation of methods:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
points.setBackground(
ResourcesCompat.getDrawable(getResources(),
R.drawable.bench_text_bg,
null));
name.setBackground(
ResourcesCompat.getDrawable(getResources(),
R.drawable.bench_text_bg,
null));
} else {
points.setBackgroundDrawable(
ResourcesCompat.getDrawable(getResources(),
R.drawable.bench_text_bg,
null);
name.setBackgroundDrawable(
ResourcesCompat.getDrawable(getResource(),
R.drawable.bench_text_bg,
null));
}
Now, it doesn’t matter what version of the app is being used as we’re going to be setting the images the same way. They now get set using setBackgroundResource()
rather than setImageDrawable()
:
points.setBackgroundResource(R.drawable.bench_text_bg);
name.setBackgroundResource(R.drawable.bench_text_bg);
You can also do the same when setting images, just change from setImageDrawable()
to setImageResource()
:
bottomBarRankIndicator.setImageResource(R.drawable.ic_points_up);
I did have a lint issue at one point with Android Studio v1.5 informing me that when I had set the attribute to app:srcCompat
on an ImageView in XML. This was “Unexpected namespace prefix ‘app’ found for tag ImageView”. Despite this the app still seemed to work fine and the image shows, so it must be a false alarm.
Fantasy Football Fix lost 2.4MB this week everyone! Let’s give it a round of applause!
So after testing this all out in debug and on all supported versions of Android I built the release. I was surprised at the difference. The app had gone from 10.5MB to 8.1MB! A 2.4MB drop. I was really happy with this. One because it removed that magic 10 number from the size, but also because the app’s second largest user country is India. And we should all know by now about trying our best to help accommodate these users, and reducing our app is size is one sure fire way to do it.
So VectorDrawableCompat is a really easy way to reduce your app size. The question is, can you beat my reduction?!
P.S Bonus material, go watch Vector All the Things by Mark Allison, one of my favourite droidcon London talks and should definitely swing you round to vectors