Over time, one problem I keep running into over and over again is dealing with resource bloat – which happens when you keep adding new resources but there’s no good way to remove the ones that are no longer in use. In a typical web project, resource bloat doesn’t really affect performance because the browser will only load what’s needed. On mobile, however, it’s a real problem because space is much more of a commodity, and all of your unused resources will end up getting shipped to the user.
To fix this, I wrote a small tool called
android-resource-remover that pinpoints unused resources and removes them from your codebase.
In Android, resources are everything. Your layout XML files define your views,
images, strings, colors, dimensions, animations, and so on. Different screen
densities across different devices make you store every image in 4-5 different
resolutions with the same name in different folders. In cases with graphical
buttons, you need to provide a different image for different button states and
then wire it all up in an additional XML in your drawable folder. This makes
it easy to have one button in 11 different files. The same goes for strings;
e.g. our app is translated into 10 different languages. Adding a new string to
the app will introduce a new
<string> tag in 10 different XML files.
If I want to stop using a button, I have to find out what image resources my drawable XML is using and then delete everything. In the case of the string that I just defined, I have to delete the string in those 10 different files and remove them inline.
Because there’s so much overhead and manual work, I pretty much never did resource cleanup.
Solution and Usage
Today, the Android Developer Tools come with a tool called Lint that gives you
great output on what is unused in your codebase. However, you still have to
remove everything yourself. For this reason we wrote a small tool called
android-resource-remover that will remove all of your unused resources based
on Lint’s output.
You can install it with:
pip install android-resource-remover
Usage is pretty easy too. You just run
in your Android project directory.
android-resource-remover expects that you
lint in your classpath. In case you don’t, you can specify the location
lint tool with
You can find more information about how to use it and the source under https://github.com/KeepSafe/android-resource-remover. In case you built your Android project with gradle, tale a look at the tools README for instructions.
One thing to note is that you might have to run
twice because of dependencies. In other words, new unused resources will
likely emerge after you run it for the first time. For instance, an unused
layout in your code will be removed on the first run. Then, when you run it
again, it will point out all the strings and graphics that have been used by
this layout, as there is no reference to them anymore.
What is the difference in APK size after running android-resource-remove on
our hide pictures app? I branched off from our develop branch to build a
different APK after removing all unused resources to compare file size. The
result is quite fascinating. Even with our rather large app (due to native
code and other libs), I can reduce the APK size by 10% by shaving off ~1MB.
Here is a
ls -la output of that dir.
-rw-r--r-- 1 philipp staff 10M Apr 30 09:22 App_without_unused_resources.apk -rw-r--r-- 1 philipp staff 11M Apr 30 09:07 App_including_unused_resources.apk
How does it work?
android-resource-remover is based off the result XML from the Android Lint tool. There are other tools out there that tell you about unused resources, but we feel strongly about using the output of the most supported tool over time. In this case, Lint from the Android project itself seemed like a solid approach; it allowed us to focus on removing the actual resources from disk and from within the other XML resource files.
Lint tool gives you a lot of things you can use to improve in your app. For
this project, we’re only looking at improvements that are tagged with
UnusedResources. So we’re parsing the entire output XML for
The slightly tricky part is that Lint output is not currently made for tools
like this, so there is no clear indication if a resource is an entire file or
just a single element in a resource.xml file (e.g. string.xml). Our current
approach is to look at the
location value of the unused resource from Lint’s
output. If it contains
column, we expect the resource to be within
a file and not the entire file.
From here on it’s pretty easy: resources that are an entire file just get
deleted. For resources that we identified as an element within a XML file, we
first parse the resource XML and then remove that element. All this happens in
the android_clean_app.py either in
While writing this, I’m contemplating whether we should just commit a patch to the Android Lint tool that gives us a more clear output about a resource being a value within a XML file or an entire file.
I hope this will help as many Android developers over time as possible. I’m very happy to hear your comments, suggestions, experiences and how you think we can improve android-resource-remover. Feel free to submit bugs or open pull requests for improvements.