Understanding the Need for Advanced Cleanup
When developing Android applications, disk space can quickly become cluttered with build outputs, Gradle caches, and IDE configuration files.
- By default, Android Studio’s “Build → Clean Project” does not remove everything.
- Caches, artifacts from multiple modules, leftover Gradle files, and build outputs can accumulate.
This article provides a single script that handles these issues comprehensively, with fancy console output showing before and after space usage. We’ll cover macOS/Linux (with Bash) and Windows (with Batch), and also clarify how the script’s Lite cleanup compares to Build → Clean Project in terms of freed disk space and project scope.
Like anything that “removes” content, use with caution.
Why Not Just Use “Build → Clean Project”?
- Limited Scope: It typically targets only the
build
folders for whichever module(s) are currently open in the IDE. - Misses
.gradle: It leaves
.gradle
untouched; you won’t reclaim that space or fix corrupted caches. - No Bulk: If you have multiple projects under one folder (e.g.,
~/AndroidStudioProjects
), you’d have to open and clean each project manually.
Lite vs. Deep Cleanup
We define two levels of cleanup in our script:
Lite Cleanup
- Removes only build output (like
build
,app/build
) so your next build is forced to recompile. - Does not remove
.gradle
(so you don’t have to re-download dependencies). - Disk Space Freed: Typically similar to Build → Clean Project, especially on a single-module project.
Deep Cleanup
- Also removes the
.gradle
folder, reclaiming significant disk space if Gradle caches have grown large. - Space Freed: Significantly more than a standard or IDE-based clean because
.gradle
can be gigabytes in size.
How Does the Lite Cleanup Compare to “Build → Clean Project”?
Disk-Space Freed:
- On a single-module project, Lite cleanup and Build → Clean Project typically free about the same space (both remove
build
outputs). - On a multi-module project or in a bulk scenario, our Lite cleanup might remove build outputs from all modules/folders, whereas Build → Clean Project only cleans modules you currently have open in the IDE — so you might see slightly more disk space freed with our script.
Flexibility & Automation:
- Our Lite cleanup can be run from the command line (or CI/CD) without opening the IDE.
- You can do bulk cleanup for multiple projects in one go.
No Gradle Caches:
- Both Build → Clean Project and Lite cleanup do not remove
.gradle
. For big disk space recovery or corrupted caches, you’d need a deep cleanup.
Bottom Line
- If you’re used to Build → Clean Project on a single-project, single-module setup, Lite cleanup is roughly the same in terms of disk savings.
- However, our script is more convenient (especially for multi-module/bulk cleanup) and easily extendable to a deeper purge when needed.
1. The All-in-One macOS/Linux Script
Below is a single Bash script that supports the following parameters:
Single vs. Bulk
bulk
→ cleans all subfolders as if each one is a separate projectsingle
(default) -> cleans current project’s folder (must be inside root folder of android project).
Lite vs. Deep
lite
→ runs thegradlew/ clean
(like “Build → Clean Project” but easier to automate)deep
(default) That is much more aggressive, it deletes the .gradlew folder instead of running gradle cleanning script.
It also shows the detected modules (by scanning for build.gradle
or build.gradle.kts
), includes buildSrc support, and prints largest directories after the cleanup for diagnostic purposes.
Why Deep-by-Default?
- Frees More Space: Removing
.gradle
can reclaim big chunks of disk space. - Avoids Redundant Downloads: By skipping
./gradlew clean
, we won’t trigger Gradle to download a distribution or libraries just to delete them immediately. - Still Optional: If you want a lighter, “build-only” cleanup, pass
lite
.
1. macOS/Linux (Bash) Version
Save the following script as android-cleanup.sh
, make it executable (chmod +x android-cleanup.sh
), and place it wherever you like (e.g., ~/Scripts
).
#!/bin/bash # # Usage Examples: # 1) Deep cleanup (no params): # ./android-cleanup.sh # 2) Lite cleanup (standard): # ./android-cleanup.sh lite # 3) Deep bulk cleanup in current folder: # ./android-cleanup.sh bulk # 4) Lite bulk cleanup: # ./android-cleanup.sh bulk lite # # Merged script: # - Deep is default (removes .gradle, etc.), skipping gradlew clean # - "lite" mode => standard, calls gradlew clean, doesn't remove .gradle # - "bulk" => clean multiple subfolders # - Lists discovered modules, cleans "buildSrc", shows largest dirs after cleanup # ################################ # Parse Script Arguments ################################ IS_BULK=false IS_DEEP=true # default is deep unless user passes 'lite' for arg in "$@"; do case "$arg" in bulk) IS_BULK=true ;; lite) IS_DEEP=false ;; deep) IS_DEEP=true ;; *) echo "Unknown argument: $arg" echo "Usage: $0 [bulk] [lite] [deep]" echo " - (no args) => deep mode" echo " - bulk => process subfolders" echo " - lite => standard cleanup (build only, plus gradlew clean)" echo " - deep => ensures we do a deep cleanup" exit 1 ;; esac done ################################ # Print Which Mode We're In ################################ if [ "$IS_DEEP" = true ]; then echo "Using DEEP cleanup mode..." else echo "Using STANDARD (lite) cleanup mode..." fi ################################ # Configure Directories to Clean ################################ if [ "$IS_DEEP" = true ]; then directories_to_clean=( "build" # Root project build "app/build" # Main app module ".gradle" # Root Gradle cache "*/build" # Any module's build directory "buildSrc/.gradle" # BuildSrc gradle cache "buildSrc/build" # BuildSrc build directory # Uncomment if you also want to remove .idea: # ".idea" ) else # Lite mode => no .gradle removal directories_to_clean=( "build" "app/build" "*/build" # Include all modules' build dirs "buildSrc/build" # BuildSrc build directory # buildSrc/.gradle intentionally omitted for standard mode ) fi ################################ # Helper Function: Clean a Single Project ################################ clean_single_project() { local project_path="$1" echo "----------------------------------------" echo "📁 Cleaning project: $project_path" cd "$project_path" || { echo "Could not enter $project_path; skipping." return } echo "----------------------------------------" echo "📊 Space usage before cleanup:" du -sh . 2>/dev/null # List discovered modules (just for info) echo "🔍 Detected modules (via build.gradle / build.gradle.kts):" find . \( -name "build.gradle" -o -name "build.gradle.kts" \) \ | sed 's/\/build\.gradle.*$//' \ | sort -u \ | while read -r module; do if [ "$module" != "." ]; then # remove "./" if present mod="${module#./}" echo " - $mod" fi done # In lite mode => run Gradle clean if present # In deep mode => skip Gradle clean to avoid downloads if [ "$IS_DEEP" = false ]; then echo "----------------------------------------" echo "🧹 Running Gradle clean (lite mode)..." if [ -f "./gradlew" ]; then ./gradlew clean else echo "⚠️ Warning: No gradlew found in current directory" fi else echo "----------------------------------------" echo "🧹 Skipping Gradle clean (deep mode)..." fi # Remove build directories using 'find' to handle wildcards echo "----------------------------------------" echo "🗑️ Removing build directories..." for dir in "${directories_to_clean[@]}"; do # We'll search for exact matches to the basename, but also # ensure the full path ends with the $dir pattern find . -type d -path "*/$dir" -exec sh -c ' echo " Removing: $1" rm -rf "$1" ' sh {} \; 2>/dev/null done # Show final space usage echo "----------------------------------------" echo "✨ Cleanup complete!" echo "📊 Space usage after cleanup:" du -sh . 2>/dev/null # Largest remaining directories - helpful for debugging echo "📊 Largest remaining directories (top 5):" # On macOS, 'du -d 2' might be 'du -n 2' or 'du -depth=2' depending on version # We'll assume GNU/BSD style works: du -h -d 2 . 2>/dev/null | sort -hr | head -n 5 echo "----------------------------------------" cd - >/dev/null || return } ################################ # Main Logic: Single or Bulk ################################ if [ "$IS_BULK" = true ]; then echo "Performing BULK cleanup in $(pwd)" for project_dir in */; do if [ -d "$project_dir" ]; then clean_single_project "$project_dir" fi done echo "Bulk cleanup complete!" else echo "Performing SINGLE-PROJECT cleanup in $(pwd)" clean_single_project "$(pwd)" fi
Usage (macOS/Linux)
- Default (no arguments) → Deep cleanup (removes
.gradle
, no Gradle tasks). - lite → Standard/lite cleanup (removes only
build
folders, callsgradlew clean
). - bulk → Process all subfolders in the current directory.
- bulk lite → Bulk, but do a lite cleanup.
- bulk deep → Redundant (since deep is default), but recognized for clarity.
2. Windows (PowerShell) Version
Save as android-cleanup.ps1 and run with PowerShell (or Windows Terminal). If blocked by policy, you can bypass via:
powershell.exe -ExecutionPolicy Bypass -File .\android-cleanup.ps1
PowerShell Execution Policy
By default, PowerShell may prevent scripts from running if not signed:
- Option 1: Temporarily bypass with
powershell.exe -ExecutionPolicy Bypass -File .\android-cleanup.ps1
- Option 2:
Set-ExecutionPolicy RemoteSigned
(orUnrestricted
) to allow local scripts to run.
Be sure you trust the script before changing these policies.
Param( [Parameter(ValueFromRemainingArguments=$true)] [String[]] $Args ) # Default: DEEP cleanup $IS_BULK = $false $IS_DEEP = $true # Parse arguments (bulk, lite, deep) foreach ($arg in $Args) { switch ($arg.ToLower()) { 'bulk' { $IS_BULK = $true } 'lite' { $IS_DEEP = $false } 'deep' { $IS_DEEP = $true } default { Write-Host "Unknown argument: $arg" Write-Host "Usage: ./android-cleanup.ps1 [bulk] [lite] [deep]" Write-Host " - (no args) => deep cleanup" Write-Host " - bulk => process subfolders" Write-Host " - lite => standard cleanup (build only, plus gradlew clean)" Write-Host " - deep => ensures deep cleanup" exit } } } if ($IS_DEEP) { Write-Host "Using DEEP cleanup mode..." } else { Write-Host "Using STANDARD (lite) cleanup mode..." } # Configure directories to clean $DirectoriesToClean = @() if ($IS_DEEP) { # Deep => remove .gradle, buildSrc caches, etc. $DirectoriesToClean += "build" $DirectoriesToClean += "app/build" $DirectoriesToClean += ".gradle" $DirectoriesToClean += "buildSrc/.gradle" $DirectoriesToClean += "buildSrc/build" $DirectoriesToClean += "*/build" # wildcard submodules # Uncomment if you also want to remove .idea: # $DirectoriesToClean += ".idea" } else { # Lite => keep .gradle, just remove build outputs $DirectoriesToClean += "build" $DirectoriesToClean += "app/build" $DirectoriesToClean += "buildSrc/build" $DirectoriesToClean += "*/build" } ######################################################################## # Clean-SingleProject - does NOT change directory if we're already there ######################################################################## function Clean-SingleProject { param($ProjectPath) Write-Host "----------------------------------------" Write-Host "📁 Cleaning project: $ProjectPath" # If in bulk mode, we need to enter each subfolder. Otherwise, do nothing. if ($IS_BULK) { # Attempt to switch into project directory try { Push-Location -LiteralPath $ProjectPath -ErrorAction Stop } catch { Write-Host "Could not enter $ProjectPath; skipping." return } } else { # Single-project mode => assume we are ALREADY inside the project folder # Do not change directory, matching mac script behavior. } Write-Host "----------------------------------------" Write-Host "📊 Space usage before cleanup:" # Approximate 'du -sh .' via summing file sizes Get-ChildItem -Recurse -File -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum | ForEach-Object { $sizeMB = [math]::Round($_.Sum / 1MB, 2) Write-Host "$sizeMB MB total (approx)" } # Detect modules by build.gradle / build.gradle.kts Write-Host "🔍 Detected modules (via build.gradle / build.gradle.kts):" $gradleFiles = Get-ChildItem -Recurse -Include build.gradle,build.gradle.kts -File -ErrorAction SilentlyContinue if ($gradleFiles) { $modules = $gradleFiles | ForEach-Object { $_.DirectoryName } | Sort-Object -Unique foreach ($modPath in $modules) { # Convert to relative path $rel = Resolve-Path -LiteralPath $modPath $cwd = Get-Location $relStr = $rel -replace [regex]::Escape($cwd.Path + "\\"), ".\" Write-Host " - $relStr" } } else { Write-Host " (No gradle files found)" } # If in lite mode => run Gradle clean if (-not $IS_DEEP) { Write-Host "----------------------------------------" Write-Host "🧹 Running Gradle clean (lite mode)..." if (Test-Path "./gradlew.bat") { Start-Process "./gradlew.bat" "clean" -NoNewWindow -Wait } elseif (Test-Path "./gradlew") { # Possibly a gradlew shell script Start-Process "powershell" "./gradlew clean" -NoNewWindow -Wait } else { Write-Host "⚠️ Warning: No gradlew found in current directory" } } else { Write-Host "----------------------------------------" Write-Host "🧹 Skipping Gradle clean (deep mode)..." } Write-Host "----------------------------------------" Write-Host "🗑️ Removing build directories..." foreach ($dirPattern in $DirectoriesToClean) { if ($dirPattern -like '*/build') { # search all subfolders named "build" $buildDirs = Get-ChildItem -Directory -Recurse -Filter build -ErrorAction SilentlyContinue foreach ($bDir in $buildDirs) { Write-Host " Removing: $($bDir.FullName)" Remove-Item -LiteralPath $bDir.FullName -Recurse -Force -ErrorAction SilentlyContinue } } else { # direct path if (Test-Path $dirPattern) { $fullPath = Resolve-Path $dirPattern -ErrorAction SilentlyContinue if ($fullPath) { Write-Host " Removing: $($fullPath.ToString())" Remove-Item $fullPath -Recurse -Force -ErrorAction SilentlyContinue } } } } Write-Host "----------------------------------------" Write-Host "✨ Cleanup complete!" Write-Host "📊 Space usage after cleanup:" Get-ChildItem -Recurse -File -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum | ForEach-Object { $sizeMB = [math]::Round($_.Sum / 1MB, 2) Write-Host "$sizeMB MB total (approx)" } Write-Host "📊 Largest remaining directories (top 5):" Get-ChildItem -Directory -Recurse -ErrorAction SilentlyContinue | ForEach-Object { $subTotal = ($_ | Get-ChildItem -Recurse -File -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum [PSCustomObject]@{ Path = $_.FullName SizeMB = [math]::Round($subTotal / 1MB, 2) } } | Sort-Object SizeMB -Descending | Select-Object -First 5 | ForEach-Object { Write-Host (" {0} MB {1}" -f $_.SizeMB, $_.Path) } Write-Host "----------------------------------------" # If we entered in bulk mode, pop back out if ($IS_BULK) { Pop-Location | Out-Null } } # Main logic if ($IS_BULK) { Write-Host "Performing BULK cleanup in $(Get-Location)" $subfolders = Get-ChildItem -Directory foreach ($folder in $subfolders) { Clean-SingleProject $folder.FullName } Write-Host "Bulk cleanup complete!" } else { Write-Host "Performing SINGLE-PROJECT cleanup in $(Get-Location)" # We'll call Clean-SingleProject with the same folder, but no directory change Clean-SingleProject (Get-Location) }
Usage Windows
- No arguments → Deep cleanup on the current folder, no directory changes.
lite
→ Standard cleanup in the current folder, calls Gradle clean.bulk
→ Check each subfolder as a separate Android project, do a deep cleanup.bulk lite
→ Bulk but do the “lite” approach.
Special thanks to Jahangir Jadi for assisting during the creation and testing phase of the PowerShell version of the script.
Example Script Usage
Lite Single Project (Mac)
When you specify lite on a single project, it effectively calls
./gradlew clean
for you, without opening the project inside Android Studio. You’ll see output about what modules were detected and how much space was reclaimed.
% ~/scripts/android-cleaner.sh lite Using STANDARD (lite) cleanup mode... Performing SINGLE-PROJECT cleanup in /Users/ianyfantakis/AndroidStudioProjects/SampleProject ---------------------------------------- 📁 Cleaning project: /Users/ianyfantakis/AndroidStudioProjects/SampleProject ---------------------------------------- 📊 Space usage before cleanup: 219M . 🔍 Detected modules (via build.gradle / build.gradle.kts): - app ---------------------------------------- 🧹 Running Gradle clean (lite mode)... BUILD SUCCESSFUL in 2s 1 actionable task: 1 executed ---------------------------------------- 🗑️ Removing build directories... ---------------------------------------- ✨ Cleanup complete! 📊 Space usage after cleanup: 5.8M . 📊 Largest remaining directories (top 5): 5.8M . 3.8M ./.gradle/8.9 3.8M ./.gradle 1.3M ./.git 1.2M ./.git/objects ----------------------------------------
As you can see, the project shrank from 219MB to 5.8MB.
Deep Single Project (Mac)
If we don’t specify anything, “deep” is the default. This is significantly faster because there’s no Gradle script running, and the .gradle
folder is removed, freeing even more space.
% ~/scripts/android-cleaner.sh Using DEEP cleanup mode... Performing SINGLE-PROJECT cleanup in /Users/ianyfantakis/AndroidStudioProjects/SampleProject ---------------------------------------- 📁 Cleaning project: /Users/ianyfantakis/AndroidStudioProjects/SampleProject ---------------------------------------- 📊 Space usage before cleanup: 218M . 🔍 Detected modules (via build.gradle / build.gradle.kts): - app ---------------------------------------- 🧹 Skipping Gradle clean (deep mode)... ---------------------------------------- 🗑️ Removing build directories... Removing: ./app/build Removing: ./.gradle ---------------------------------------- ✨ Cleanup complete! 📊 Space usage after cleanup: 2.0M . 📊 Largest remaining directories (top 5): 2.0M . 1.3M ./.git 1.2M ./.git/objects 588K ./app 560K ./app/src ----------------------------------------
We went from 218MB to 2MB — a huge savings.
Job Offers
Bulk Lite (Mac)
% ~/scripts/android-cleaner.sh bulk lite Using STANDARD (lite) cleanup mode... Performing BULK cleanup in /Users/ianyfantakis/AndroidStudioProjects ---------------------------------------- 📁 Cleaning project: CameraRecorder/ ---------------------------------------- 📊 Space usage before cleanup: 92M . 🔍 Detected modules (via build.gradle / build.gradle.kts): - app ---------------------------------------- 🧹 Running Gradle clean (lite mode)... BUILD SUCCESSFUL in 1s 1 actionable task: 1 executed ---------------------------------------- 🗑️ Removing build directories... ---------------------------------------- ✨ Cleanup complete! 📊 Space usage after cleanup: 1.7M . 📊 Largest remaining directories (top 5): 1.7M . 1.4M ./.gradle 1.2M ./.gradle/8.4 204K ./.gradle/buildOutputCleanup 160K ./app ---------------------------------------- ---------------------------------------- 📁 Cleaning project: ColorChanger1 copy 2/ ---------------------------------------- 📊 Space usage before cleanup: 44M . 🔍 Detected modules (via build.gradle / build.gradle.kts): - app ---------------------------------------- 🧹 Running Gradle clean (lite mode)... Starting a Gradle Daemon (subsequent builds will be faster) BUILD SUCCESSFUL in 4s 2 actionable tasks: 2 executed ---------------------------------------- 🗑️ Removing build directories... ---------------------------------------- ✨ Cleanup complete! 📊 Space usage after cleanup: 5.4M . 📊 Largest remaining directories (top 5): 5.4M . 4.7M ./.gradle 3.5M ./.gradle/7.2 1.0M ./.gradle/buildOutputCleanup 468K ./.idea ----------------------------------------
Bulk Deep (Mac)
% ~/scripts/android-cleaner.sh bulk Using DEEP cleanup mode... Performing BULK cleanup in /Users/ianyfantakis/AndroidStudioProjects ---------------------------------------- 📁 Cleaning project: CameraRecorder/ ---------------------------------------- 📊 Space usage before cleanup: 92M . 🔍 Detected modules (via build.gradle / build.gradle.kts): - app ---------------------------------------- 🧹 Skipping Gradle clean (deep mode)... ---------------------------------------- 🗑️ Removing build directories... Removing: ./app/build Removing: ./.gradle ---------------------------------------- ✨ Cleanup complete! 📊 Space usage after cleanup: 312K . 📊 Largest remaining directories (top 5): 312K . 160K ./app 148K ./app/src 64K ./gradle/wrapper 64K ./gradle ---------------------------------------- ---------------------------------------- 📁 Cleaning project: ColorChanger/ ---------------------------------------- 📊 Space usage before cleanup: 44M . 🔍 Detected modules (via build.gradle / build.gradle.kts): - app ---------------------------------------- 🧹 Skipping Gradle clean (deep mode)... ---------------------------------------- 🗑️ Removing build directories... Removing: ./app/build Removing: ./build Removing: ./.gradle ---------------------------------------- ✨ Cleanup complete! 📊 Space usage after cleanup: 752K . 📊 Largest remaining directories (top 5): 752K . 468K ./.idea 388K ./.idea/libraries 180K ./app 160K ./app/src ----------------------------------------
Bulk Deep (Windows PowerShell)
PS D:\TestProjects> .\android-cleanup.ps1 bulk Using DEEP cleanup mode... Performing BULK cleanup in D:\TestProjects ---------------------------------------- 📁 Cleaning project: D:\TestProjects\LogMyCareCarer ---------------------------------------- 📊 Space usage before cleanup: 852.48 MB total (approx) 🔍 Detected modules (via build.gradle / build.gradle.kts): - D:\TestProjects\LogMyCareCarer - D:\TestProjects\LogMyCareCarer\app ---------------------------------------- 🧹 Skipping Gradle clean (deep mode)... ---------------------------------------- 🗑️ Removing build directories... Removing: D:\TestProjects\LogMyCareCarer\build Removing: D:\TestProjects\LogMyCareCarer\app\build Removing: D:\TestProjects\LogMyCareCarer\.gradle Removing: D:\TestProjects\LogMyCareCarer\app\build Removing: D:\TestProjects\LogMyCareCarer\app\build ---------------------------------------- ✨ Cleanup complete! 📊 Space usage after cleanup: 36.95 MB total (approx) 📊 Largest remaining directories (top 5): 35.91 MB D:\TestProjects\LogMyCareCarer\app 25.73 MB D:\TestProjects\LogMyCareCarer\app\release 8.52 MB D:\TestProjects\LogMyCareCarer\app\src 8.52 MB D:\TestProjects\LogMyCareCarer\app\src\main 4.21 MB D:\TestProjects\LogMyCareCarer\app\src\main\res ---------------------------------------- ---------------------------------------- 📁 Cleaning project: D:\TestProjects\LogMyCareManager ---------------------------------------- 📊 Space usage before cleanup: 566.32 MB total (approx) 🔍 Detected modules (via build.gradle / build.gradle.kts): - D:\TestProjects\LogMyCareManager - D:\TestProjects\LogMyCareManager\app ---------------------------------------- 🧹 Skipping Gradle clean (deep mode)... ---------------------------------------- 🗑️ Removing build directories... Removing: D:\TestProjects\LogMyCareManager\build Removing: D:\TestProjects\LogMyCareManager\app\build Removing: D:\TestProjects\LogMyCareManager\.gradle Removing: D:\TestProjects\LogMyCareManager\app\build Removing: D:\TestProjects\LogMyCareManager\app\build ---------------------------------------- ✨ Cleanup complete! 📊 Space usage after cleanup: 24.74 MB total (approx) 📊 Largest remaining directories (top 5): 24.63 MB D:\TestProjects\LogMyCareManager\app 17.52 MB D:\TestProjects\LogMyCareManager\app\release 5.11 MB D:\TestProjects\LogMyCareManager\app\src\main 5.11 MB D:\TestProjects\LogMyCareManager\app\src 3.5 MB D:\TestProjects\LogMyCareManager\app\src\main\res ---------------------------------------- PS D:\TestProjects>
Wrap-Up
With deep as the default, this script reclaims maximum space without redundant Gradle downloads. If you only want a “build-only” cleanup (like a normal “Gradle clean”), pass lite. Optionally add
bulk to clean multiple subfolders (useful if you keep many Android projects in one directory).
Final Thoughts
- Module Detection: We display modules by scanning for
build.gradle
/build.gradle.kts
. - Wildcard Path Handling:
*/build
ensures submodules aren’t missed. - BuildSrc Support: We explicitly remove
buildSrc/.gradle
andbuildSrc/build
for advanced Gradle builds. - Diagnostic: We print largest directories left behind to help you track down big folders.
Enjoy the convenience of a single script that far exceeds Android Studio’s built-in Clean Project by removing caches, supporting multi-module or multi-project scenarios, and automating everything via bulk mode. Happy cleaning!
This article is previously published on proandroiddev.com.