188

I have a huge Android project with many strings declared in strings.xml. I wanted to remove unused strings in strings.xml.

Is there any easy way to do so?

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
user556956
  • 1,891
  • 2
  • 12
  • 6

9 Answers9

284

On Android Studio:

Menu -> Analyze -> Run Inspection by Name -> Unused resources

Check File mask(s) checkbox and put strings.xml in the text field.

jakub.g
  • 38,512
  • 12
  • 92
  • 130
Oded Breiner
  • 28,523
  • 10
  • 105
  • 71
  • 2
    Then you can define `Custom scope`, choosing `Production classes` -> `app` -> `values` to find unused strings, colors ... – Jemshit Nov 03 '15 at 12:03
  • 3
    With SDK Tools 26.0.2 this doesn't find my unused strings while "Find usages" doesn't show any usage of them (and it does for those actually used). – user905686 Aug 28 '17 at 08:27
  • 1
    BTW when a string is actually used (referenced dynamically in code), you can suppress linter warnings with `tools:ignore="UnusedResources"` – jakub.g Sep 25 '17 at 16:49
  • 9
    this one is not working as expected. I have tried with adding unused string and inspect, but it is not able to identify it – chikka.anddev Mar 14 '18 at 12:46
  • 2
    This seems broken, it thought a bunch of my strings were unused, but a quick "find usages" found use. Be careful. – szaske Feb 12 '20 at 17:15
58

Here is another solution that is fairly easy. In the Android Studio menu go to

Refactor > Remove Unused Resources....

enter image description here

Click Preview to see what the unused resources are and selectively remove them.

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
  • 3
    This removed a lot of resources which were actually used. Had to manually undelete a lot of stuff – stoefln Jan 16 '18 at 14:12
  • 2
    @stoefln, if you click Preview, you can manually choose what to delete and not delete. – Suragch Jan 16 '18 at 15:32
  • 2
    take care with that "Delete unused@id declarations too". It deleted me lots of id's that my code was actually using (Kotlin Android Extension plugin - that will allow recovering views from Activities, Fragments, and Views) – Dan Alboteanu Dec 15 '18 at 13:02
32

In my case "Run Inspection by Name" didnt work, despite the fact I was using "Remove unused resources".

Solution:

  1. Open strings.xml
  2. Secondary click
  3. Refactor --> Remove Unused Resources

I have no clue why "Remove Unused Resources" works one way but not the other.

cutiko
  • 9,887
  • 3
  • 45
  • 59
  • 2
    You can do it also in the project explorer, select the module you want, then right click and refactor>remove unused resources, the remove any kind of resource like unused drawables – FRL Nov 23 '16 at 18:19
22

With ADT 16 you can do it as simple as possible. Update to ADT 16 and use Android Lint. It is really amazing tool. It can find all unused resources (not only strings) and many more. From its official site:

Here are some examples of the types of errors that it looks for:

- Missing translations (and unused translations)
- Layout performance problems (all the issues the old layoutopt tool used to find, and more)
- Unused resources
- Inconsistent array sizes (when arrays are defined in multiple configurations)
- Accessibility and internationalization problems (hardcoded strings, missing contentDescription, etc)
- Icon problems (like missing densities, duplicate icons, wrong sizes, etc)
- Usability problems (like not specifying an input type on a text field)
- Manifest errors
and many more.
Andrei Buneyeu
  • 6,662
  • 6
  • 35
  • 38
  • 14
    As of ADT 20.0.2 Android Lint does not find unused Strings, nor does it claim to. I just tested it by adding a string with a completely random id and then running Lint. I could not vote reply above down, because I don't have enough reputation :(. – Frank Harper Jul 31 '12 at 03:10
  • As @FrankHarper said: it did not previously. As Lord Flash said, it does now: `Warning: The resource R.string.... appears to be unused [UnusedResources] [lint] some text` – serv-inc Nov 04 '15 at 08:26
8

This is how I did it with Android 3.3.

Check in any unsaved changes to your repository.

  • Right click your App's module -> Refactor -> Remove Unused Resources -> Preview
  • In the Refactoring Preview, collapse both the views ('Items to be deleted' & 'Unused Resource Declarations')
  • Right click 'Items to be deleted' -> Exclude
  • Right click 'Unused Resource Declarations' -> Exclude
  • Now expand 'Unused Resource Declarations' and under that locate your app specific strings.xml (there would be multiple strings.xmls)
  • Right click that strings.xml -> Include
  • Do Refactor! All unused strings from the xml file are deleted!

Note: Try building the project. If compilation fails, its most likely that these strings.xml is being referred from some layout/menu xmls, which themselves are unused. So those layout xmls can also be deleted manually!

Build and run. Test!

AAP
  • 1,246
  • 12
  • 21
3

To check string.xml.

It's easy (at least in my version of Eclipse)

In Eclipse for Android (I have version v22.6.2-1085508)

  • Right click on the project name in "Package explorer"
  • Select "Android Tools".
  • Select "Run Lint: Check for common Errors".

Now when you open strings.xml, you will see that unused string are highlighted.

You can fix other potential issues.

A.J.
  • 1,520
  • 17
  • 22
Gabriel Klein
  • 367
  • 2
  • 6
3

In Android Studio Press

Ctlr+Alt+Shift+i

Select -> Unused resources
It shows you unused unused strings and icons.

Thanks Happy coding :)

Happy Singh
  • 376
  • 3
  • 8
-1

For missing translation only:

Using InteliJ, click on the panel bar of your InteliJ: "Analyze" > "Run Inspection by Name" > Type in: Incomplete translation

sancho21
  • 3,511
  • 1
  • 39
  • 45
-1

Run this script from root of your project.

for resourcefile in `find res/values/*.xml`; do
  for stringname in `grep '.*/\1/g'`; do
    count1=`grep -rc "R.string.${stringname}" src | egrep -v ':0$' | wc -l`
    count2=`grep -rc "@string/${stringname}" res/layout | egrep -v ':0$' | wc -l`
    count3=`grep -rc "@string/${stringname}" res/menu | egrep -v ':0$' | wc -l`
    count4=`grep -rc "@string/${stringname}" AndroidManifest.xml | egrep -v '^0$' | wc -l`
    count5=`grep -rc "@string/${stringname}" res/xml | egrep -v ':0$' | wc -l`
    if [ $count1 -eq 0 -a $count2 -eq 0 -a $count3 -eq 0 -a $count4 -eq 0 -a $count5 -eq 0 ]; then
      echo $resourcefile : $stringname
    fi
  done
done

for resourcename in `find res/drawable* -type f -name '*.???'`; do
  resource=`echo $resourcename | xargs basename | sed "s/^\(.*\)\....$/\1/g"`
  count1=`grep -rc "R\.drawable\.${resource}" src | egrep -v ':0$' | wc -l`
  count2=`grep -rc "@drawable/${resource}" res/layout | egrep -v ':0$' | wc -l`
  count3=`grep -rc "@drawable/${resource}" res/drawable*/*.xml | egrep -v ':0$' | wc -l`
  count4=`grep -rc "@drawable/${resource}" res/menu | egrep -v ':0$' | wc -l`
  count5=`grep -rc "@drawable/${resource}" AndroidManifest.xml | egrep -v '^0$' | wc -l`
  if [ $count1 -eq 0 -a $count2 -eq 0 -a $count3 -eq 0 -a $count4 -eq 0 -a $count5 -eq 0 ]; then
      echo $resourcename
  fi
done

for resourcename in `find res/layout/*.xml`; do
  resource=`echo $resourcename | xargs basename | sed "s/^\(.*\)\....$/\1/g"`
  count1=`grep -rc "R\.layout\.${resource}" src | egrep -v ':0$' | wc -l`
  if [ $count1 -eq 0 ]; then
      echo $resourcename
  fi
done

It gives me this kind of output:

res/values/activity_strings.xml : activity_more
res/values/activity_strings.xml : activity_as_reply_to
res/values/db_strings.xml : sql_backlog_count
res/values/db_strings.xml : sql_backlog_update_last_resend
...
Carl D'Halluin
  • 1,052
  • 10
  • 14
  • Cool approach but does it check if the resource name is not in comments or strings? It needs some modifications to be compatible with new Android Studio project structure too. – Mohammad Jafar Mashhadi Jul 08 '15 at 09:05