A simple utility to remove unused resources in your Android app to lower the size of the APK. It's based on the Android lint tool output.

Overview

Build Status

resource-remover android-resource-remover

android-resource-remover is utility that removes unused resources reported by Android Lint from your project. The goal is to reduce your APK size and keep the app clean from unused stuff.

Getting started

Requirements:

  • Python >= 2.7.*
  • ADT >= 16

To install run:

pip install android-resource-remover

Usage - general

Open the directory where your app is located and run

android-resource-remover

Android resources have dependencies to each other. This means that after running resource-remover the first time, it will clean up unused resources file that hold a reference to other resources. You can run this resource remover multiple times until there is no more unused resources to be removed. We've been running it up to 4 times in a row.

Use with gradle

android-resource-remover is build on top of android lint. If you have a gradle project you have to run lint within your gradle build scripts and then use the lint-result.xml as the input file for android-resource-remover

e.g.

./gradlew clean build :lint && android-resource-remover --xml build/outputs/lint-results.xml

Options

--help

Prints help message.

--lint

Full path to the lint tool like: d:\Dev\Android SDK\tools\lint

This will be executed as the lint command. If not provided it assumes the lint command in available and runs: lint

--app

Full path to the android app like: d:\Dev\My_Android_App

If not provided it assumes the current directory is the app's root directory.

--xml

Use existing lint result. If provided lint won't be run.

--ignore-layouts

Ignore layout directory

Expected behavior

Resource ID in code not found

If you have references to elements in an old layout that you're not using anymore, you will get a compile error that the ID (R.id.<something>) can not be found. The reason is that the resource file that contained R.id.<something> has been removed as it was not used any more. Time to clean up your code.

FAQ

Q: installing dependency lxml failed with clang: error: unknown argument: '-mno-fused-madd' [-Wunused-command-line-argument-hard-error-in-future]
A: http://stackoverflow.com/a/22322645

Q: installing dependency lxml failed with fatal error: 'libxml/xmlversion.h' file not found
A: There are several ways to fix this listed on stackoverflow http://stackoverflow.com/questions/19548011/cannot-install-lxml-on-mac-os-x-10-9

Issues and PR

When opening an issue please include as much info as possible. pip.log, python varsion/info, os version/info might all be help us understanding what's the problem.

In PR please keep the formatting.

Licence

Apache version 2.0

Comments
  • Problem removing unused dimens and strings

    Problem removing unused dimens and strings

    When using the latest version of your script, the console output correctly prints out the message

    removing ('dimen', "<dimen_name>") from resource ./res/values/dimens.xml removing ('string', "<string_name>") from resource ./res/values/strings.xml

    for all dimens and strings files but doesn't actually remove the said unused resource from the file. Is this a known issue?

    opened by sb673 11
  • Execution Error; Seeking Help

    Execution Error; Seeking Help

    After installing (via sudo pip install android-resource-remover) successfully, cd-ing into the app directory and executing android-resource-remover I receive the following error:

    Traceback (most recent call last):
      File "/usr/local/bin/android-resource-remover", line 9, in <module>
        load_entry_point('android-resource-remover==0.1.5', 'console_scripts', 'android-resource-remover')()
      File "/usr/local/lib/python2.7/dist-packages/android_clean_app.py", line 141, in main
        lint_result_path, app_dir, ignore_layouts = run_lint_command()
      File "/usr/local/lib/python2.7/dist-packages/android_clean_app.py", line 77, in run_lint_command
        call_result = subprocess.call([lint, app_dir, '--xml', lint_result])
      File "/usr/lib/python2.7/subprocess.py", line 522, in call
        return Popen(*popenargs, **kwargs).wait()
      File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
        errread, errwrite)
      File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child
        raise child_exception
    OSError: [Errno 2] No such file or directory
    

    Environment :

    • Linux Ubuntu 14.04 LTS
    • Python 2.7.6
    • Android Studio 1.3
    • JRE 1.8

    Help Appreciated :)

    opened by jigyasa-grover 8
  • IOError: Error reading file 'build/outputs/lint-results.xml'

    IOError: Error reading file 'build/outputs/lint-results.xml'

    Hi, Unfortunately, I wasn't able to get it into for two days so decided to get some help. For some reasons I'm not able to use your suggested command, ./gradlew clean build :lint && android-resource-remover --xml build/outputs/lint-results.xml.

    • build tries to create a release and since I'm work on company project and its credential isn't in build.gradle file so process fails.
    • Gradle :lint is not in root of your project.

    So what I do is I first create a debug .apk in normal way. Second, I run lint from Gradle window, My-app/app/verification/lint. So lint-results.xml will be created in my build/output folder. I run this command in terminal now android-resource-remover --xml build/outputs/lint-results.xml. Then I get following error.

    I'm using Android Studio 2.0 Preview 5 on Ubuntu 14.04 LTS. Any suggestion would be appreciated. Thanks.

    screenshot from 2016-01-19 12 23 52

    opened by Hesamedin 7
  • "Running the command failed"

    When I run android-resource-remover inside the project directory under Ubuntu Trusty, it results in:

    *Help text*
    [...]
    Running the command failed. Try running it from the console. Arguments for subprocess.call: ['lint', '.', '--xml', './lint-result.xml']
    Traceback (most recent call last):
      File "/usr/local/bin/android-resource-remover", line 9, in <module>
        load_entry_point('android-resource-remover==0.1.0', 'console_scripts', 'android-resource-remover')()
      File "/usr/local/lib/python2.7/dist-packages/android_clean_app.py", line 137, in main
        issues = parse_lint_result(lint_result_path)
      File "/usr/local/lib/python2.7/dist-packages/android_clean_app.py", line 85, in parse_lint_result
        root = ET.parse(lint_result_path).getroot()
      File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 1182, in parse
        tree.parse(source, parser)
      File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 647, in parse
        source = open(source, "rb")
    IOError: [Errno 2] No such file or directory: './lint-result.xml'
    
    opened by infinitnet 5
  • unicodeDecodeerror

    unicodeDecodeerror

             I run the command "pip instatll android-resource-remover", then received an error like that:
    

    unicodeDecodeerror gbk codec can't decode byte 0x80

    opened by t12x3456 5
  • Need clarification

    Need clarification

    @ca77y So i ran your tool with lint results xml file and it gave me a bunch of output mentioning removing strings ... all the output was mentioning removal of strings from libraries that are used inside the project, none of the actual unused resources from strings.xml and drawable folders were removed. I ran lint again in android studio and all the unused icons were still there

    opened by manyata 4
  • Why i got an error when running android-resource-remover

    Why i got an error when running android-resource-remover

    Traceback (most recent call last): File "D:\Python\lib\runpy.py", line 162, in run_module_as_main "main", fname, loader, pkg_name) File "D:\Python\lib\runpy.py", line 72, in run_code exec code in run_globals File "D:\Python\Scripts\android-resource-remover.exe__main.py", line 9, in File "D:\Python\lib\site-packages\android_clean_app.py", line 141, in main lint_result_path, app_dir, ignore_layouts = run_lint_command() File "D:\Python\lib\site-packages\android_clean_app.py", line 78, in run_lint_ command call_result = subprocess.call([lint, app_dir, '--xml', lint_result]) File "D:\Python\lib\subprocess.py", line 522, in call return Popen(_popenargs, *_kwargs).wait() File "D:\Python\lib\subprocess.py", line 710, in init errread, errwrite) File "D:\Python\lib\subprocess.py", line 958, in _execute_child startupinfo) WindowsError: [Error 2]

    opened by CharonChui 4
  • It would be great to support ExtraTranslation removal

    It would be great to support ExtraTranslation removal

    Here the XML node with lint 24.0.1

        <issue
            id="ExtraTranslation"
            severity="Error"
            message="&quot;`loading_more`&quot; is translated here but not found in default locale"
            category="Correctness:Messages"
            priority="6"
            summary="Extra translation"
            explanation="If a string appears in a specific language translation file, but there is no corresponding string in the default locale, then this string is probably unused. (It&apos;s technically possible that your application is only intended to run in a specific locale, but it&apos;s still a good idea to provide a fallback.).
    
    Note that these strings can lead to crashes if the string is looked up on any locale not providing a translation, so it&apos;s important to clean them up."
            errorLine1="    &lt;string name=&quot;loading_more&quot;>Chargement&lt;/string>"
            errorLine2="            ~~~~~~~~~~~~~~~">
            <location
                file="res/values-fr/strings.xml"
                line="5"
                column="13"/>
        </issue>
    
    enhancement 
    opened by eboudrant 4
  • The lint parser add an extra '`' in the resource name which don't remove the res value

    The lint parser add an extra '`' in the resource name which don't remove the res value

    The lint parser add an extra '`' in the resource name which don't remove the res value

    removing ('string', 'loading_more`') from resource res/values/strings.xml
    

    Used OSX Maverick with an output of Gradle Lint :

    <?xml version="1.0" encoding="UTF-8"?>
    <issues format="4" by="lint 24.0.1">
    ...
    
    bug 
    opened by eboudrant 4
  • OSError: [Errno 2] No such file or directory

    OSError: [Errno 2] No such file or directory

    Run the "android-resource-remover" command in ubuntu, it's output error: Traceback (most recent call last): File "/usr/local/bin/android-resource-remover", line 9, in load_entry_point('android-resource-remover==0.1.5', 'console_scripts', 'android-resource-remover')() File "/usr/local/lib/python2.7/dist-packages/android_clean_app.py", line 141, in main lint_result_path, app_dir, ignore_layouts = run_lint_command() File "/usr/local/lib/python2.7/dist-packages/android_clean_app.py", line 77, in run_lint_command call_result = subprocess.call([lint, app_dir, '--xml', lint_result]) File "/usr/lib/python2.7/subprocess.py", line 522, in call return Popen(_popenargs, *_kwargs).wait() File "/usr/lib/python2.7/subprocess.py", line 710, in init errread, errwrite) File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child raise child_exception OSError: [Errno 2] No such file or directory

    opened by micstart 3
  • failed to install

    failed to install

    # pip install android-resource-remover

    in terminal : at the very bottom

    Command "/usr/bin/python -c "import setuptools, tokenize;__file__='/private/var/folders/ht/sg39cnfx7b7fpz5jx65r8tvc0000gp/T/pip-build-CuOnJy/lxml/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /var/folders/ht/sg39cnfx7b7fpz5jx65r8tvc0000gp/T/pip-_D9qqa-record/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /private/var/folders/ht/sg39cnfx7b7fpz5jx65r8tvc0000gp/T/pip-build-CuOnJy/lxml
    

    Environment :

    OSX El-Capitan XCode CLI Is installed

    opened by azizimusa 3
  • Bump lxml from 3.3.3 to 4.9.1

    Bump lxml from 3.3.3 to 4.9.1

    Bumps lxml from 3.3.3 to 4.9.1.

    Changelog

    Sourced from lxml's changelog.

    4.9.1 (2022-07-01)

    Bugs fixed

    • A crash was resolved when using iterwalk() (or canonicalize()) after parsing certain incorrect input. Note that iterwalk() can crash on valid input parsed with the same parser after failing to parse the incorrect input.

    4.9.0 (2022-06-01)

    Bugs fixed

    • GH#341: The mixin inheritance order in lxml.html was corrected. Patch by xmo-odoo.

    Other changes

    • Built with Cython 0.29.30 to adapt to changes in Python 3.11 and 3.12.

    • Wheels include zlib 1.2.12, libxml2 2.9.14 and libxslt 1.1.35 (libxml2 2.9.12+ and libxslt 1.1.34 on Windows).

    • GH#343: Windows-AArch64 build support in Visual Studio. Patch by Steve Dower.

    4.8.0 (2022-02-17)

    Features added

    • GH#337: Path-like objects are now supported throughout the API instead of just strings. Patch by Henning Janssen.

    • The ElementMaker now supports QName values as tags, which always override the default namespace of the factory.

    Bugs fixed

    • GH#338: In lxml.objectify, the XSI float annotation "nan" and "inf" were spelled in lower case, whereas XML Schema datatypes define them as "NaN" and "INF" respectively.

    ... (truncated)

    Commits
    • d01872c Prevent parse failure in new test from leaking into later test runs.
    • d65e632 Prepare release of lxml 4.9.1.
    • 86368e9 Fix a crash when incorrect parser input occurs together with usages of iterwa...
    • 50c2764 Delete unused Travis CI config and reference in docs (GH-345)
    • 8f0bf2d Try to speed up the musllinux AArch64 build by splitting the different CPytho...
    • b9f7074 Remove debug print from test.
    • b224e0f Try to install 'xz' in wheel builds, if available, since it's now needed to e...
    • 897ebfa Update macOS deployment target version from 10.14 to 10.15 since 10.14 starts...
    • 853c9e9 Prepare release of 4.9.0.
    • d3f77e6 Add a test for https://bugs.launchpad.net/lxml/+bug/1965070 leaving out the a...
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • 3rd part res

    3rd part res

    when we develop android app, we import 3rd part dependency. Some of them have resource, which should be imported by handle. some 3rd part resource are used, some are not used.

    how to remove these resource without using?

    opened by pighead4u 0
Owner
Keepsafe
Empowering the average person’s digital privacy we’re innovating on existing privacy, crypto and security technology. Over 50 million users.
Keepsafe
Generate inspections from output of executables

tool-to-inspection Template ToDo list Create a new IntelliJ Platform Plugin Template project. Get known with the template documentation. Verify the pl

null 2 Oct 23, 2021
A command line tool that helps bulk manage resources in an Android project

Resource Mover ResourceMover is a command line tool that helps bulk manage resources in an Android project. Installation Clone project Build CLI jar u

Shopify 4 Dec 24, 2021
This is a Android Studio/ IntelliJ IDEA plugin to localize your Android app, translate your string resources automactically.

#Android Localizationer This is a Android Studio/ IntelliJ IDEA plugin to localize your Android app, translate your string resources automactically. T

Wesley Lin 822 Dec 8, 2022
Android Resource Manager application to manage and analysis your app resources with many features like image resize, Color, Dimens and code Analysis

Android Resource Manager application to manage and analysis your app resources with many features like image resize, Color, Dimens and code Analysis

Amr Hesham 26 Nov 16, 2022
Automated-build-android-app-with-github-action - CI/CD Automated Build Android App Bundle / APK / Signed With Github Action

Automated Build Android With Using Github Action Project Github Action Script Us

Faisal Amir 34 Dec 19, 2022
A surgical debugging tool to uncover the layers under your app.

Scalpel DEPRECATED! Android Studio 4.0's layout inspector now includes a live-updating 3D view. Use it! A surgical debugging tool to uncover the layer

Jake Wharton 2.8k Jan 3, 2023
A tool to install components of the Android SDK into a Maven repository or repository manager to use with the Android Maven Plugin, Gradle and other tools.

Maven Android SDK Deployer Original author including numerous fixes and changes: Manfred Moser [email protected] at simpligility technologies i

simpligility 1.4k Dec 27, 2022
A tool to install components of the Android SDK into a Maven repository or repository manager to use with the Android Maven Plugin, Gradle and other tools.

Maven Android SDK Deployer Original author including numerous fixes and changes: Manfred Moser [email protected] at simpligility technologies i

simpligility 1.4k Dec 27, 2022
A super fast build tool for Android, an alternative to Instant Run

Freeline Freeline is a super fast build tool for Android and an alternative to Instant Run. Caching reusable class files and resource indices, it enab

Alibaba 5.5k Jan 2, 2023
Command-line tool to count per-package methods in Android .dex files

dex-method-counts Simple tool to output per-package method counts in an Android DEX executable grouped by package, to aid in getting under the 65,536

Mihai Parparita 2.6k Nov 25, 2022
Android Material Design Theme UI and Tool Library. Support: 4.0.3~O

GitHub OSChina 中文 English Genius-Android Genius-Android: by Material Design style and some commonly used packages. Starting in 2015, The divided into

Qiujuer 2.3k Dec 27, 2022
Android Merge Tool

AMT The Android Merge Tool (AMT) does what the name suggests: it merges arbitrary Android apps into a single merged app. As input it takes a number of

FoelliX 23 Nov 8, 2022
Android Studio's Vector Drawable conversion tool in convenient packaging.

Vector Drawable Tool This repository is simply a repackaging of the vector drawable tool from the Android Studio source code. The included Gradle file

Ryan Harter 55 Sep 26, 2022
Localization tool for Android Studio Projects

Android Strings Resource Language Diff tool In the event any additional languages are intended to be supported by your app. You can use this strings-d

Braxton Nunnally 1 Mar 24, 2022
Tool for create complex morphing animations using VectorDrawables (allows morphing between any pair of SVG images)

VectAlign VectAlign (a.k.a. VectorDrawableAlign) is a developer's tool which automagically aligns two VectorDrawable "pathData" strings (or SVG images

Stefano Bonetta 2k Dec 29, 2022
GPS tracking tool for OpenStreetMap

OSMTracker for Android™ official source code repository is https://github.com/labexp/osmtracker-android. For more information about the project, docum

Laboratorio Experimental (ITCR @ SIUA) 455 Dec 25, 2022