Hunting Unused Android Resources with Lint

I love Lint. I love Lint because it mocks me. Lint mocks me with little yellow markers pointing out questionable code that I need to tidy, and being on the OCD-ish side, I do that.

Lint can also generate a full warnings and errors report. The report can be (and depending on your code base, often is) overwhelming, but a fairly straightforward-to-find section is the "Unused Resources". Unused resources (layouts, strings, colors, drawables, etc.) bloat the application and slow down builds. So obviously, these jerks have got to go.

Unused resources tend to hide in the project structure (since by definition they are unreferenced by the rest of the code). This is where the Lint report comes to the rescue:

  1. Open the Gradle tool window by either:
    • View -> Tool Window -> Gradle from the menu
    • Clicking on "Gradle" in the side bar
  2. Find the Lint tasks under the "All tasks" list.
    • Once the Gradle tool window has focus, you can start typing a task name to search.
    • You should see a task named "lint" followed by several "lint…" tasks for each combination of product flavor and build type.
  3. Run one of these Lint tasks:
    • Running "lint" will run each of the flavor-build-specific tasks.
    • I generally just run "lintDebug".
  4. Grab the location of the generated report once the task finishes.
    • There will be two report formats: HTML and XML.
    • Both are located in the build outputs folder of the project.
    • Reports are per module so multiple modules will generate multiple reports.
  5. Open in your viewer of choice.
  6. Seek and destroy.

Success message after running "lintDebug". Two sets of reports for a project with two modules.

Click on the "Performance" in the summary at the top, and you should see something like this.

Some things to note:

  • Report sections often get collapsed so check for a "+ X More Occurrences…" button.
  • Alternative resources are grouped together; the report will list "Additional Locations".
  • The report does NOT catch everything.
    • Orphaned ID resources, styles, styleables, and attributes will not appear in the report.
    • Hopefully, you do not have massive amounts of these guys so, while it may suck, you can just use the "Find Usages" functionality to determine if they are unused.
  • You may have resources that are only used within unused resources, e.g., a string that only appears in an unused layout. The report will not list it, but transitively speaking, the resource is unused. Keep this in mind. To avoid missing eventually orphaned resources, I try to delete complex resources like layouts and menus first, then run the report again.

So whenever your code base needs some clean up or you are trying to tweak performance, give the Lint Gradle tasks a run and try to ferret out those unused resources. App performance and your OCD-ish teammates will thank you.

Aside: "Find Usages" is one of my all-time, top five favorite keyboard shortcuts: Option+F7