Find unused classes in Android codebase
Problem
Even though Proguard and R8 removed the unused code for you at release time, you should still make effort to remove dead code to reduce confusion, increase productivity of your everyday work and onboarding.
Solution
For starter, none of the static code analysis tools (SonarQube, CheckStyle, Pmd, Findbugs, Android Lint) I know does the job.
Since Proguard and R8 removed unused classes, I followed the instructions here and generated and generated an usage.txt file
- Add
-printusage
to your proguard.pro file - Run
./gradlew app:minifyReleaseWithProguard
or./gradlew app:minifyReleaseWithR8
But the usage.txt file is big and I can clearly see some classed that are used, not dead code.
My interpretation is that usage.txt lists both removed and obsfucated classes.
So I came up with the following algorithm
- Go through usage.txt line by line, filter out noises
- See if the class name is found in mapping.txt, if it’s not, the class is removed by Proguard/ R8
To make the search for class name in mapping.txt, I stored mapping.txt’s record in a binary tree.
Give M lines of text in usage.txt and N lines of text in mapping.txt (N is pretty big; it’s 214543 lines in my small dating app; M is minuscule compared to N), the time complexity of my algorithm is M * logN
Update Dec 17 2020
Java Set data structure could have been used here instead Binary Search Tree since I have no desire to sort the classes.
Insert and search time complexity would both be O(1) while space complexity would remain only O(N).
Conclusion
There is a chance the tree is skewed and the time complexity will be close M*N. To avoid that, the tree should be kept balance during insertion.