Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I remove unused resources from third-party libraries I’ve included on Android?

The third-party libraries that I link into my app often include resource files that aren’t being used by my application, and as such, end up bloating my APK.

For example, including the Google Play services library, but not using the login button functionality; all those image and layout resources end up in my final build.

Since these resources are included in a compiled library, how can I remove them from my build?

like image 751
Colt McAnlis Avatar asked Oct 13 '15 20:10

Colt McAnlis


People also ask

How do I delete unused resources in Android?

In Android Studio Menu > Refactor > Remove Unused Resources... Select the resources you want to remove. You can exclude resources you want to keep by right-clicking on the resource item. Use Do Refactor to remove all Resources at once.

What is third party library in Android?

The third-party libraries are reusable resources that are widely employed in Android Apps. While the third-party libraries provide a variety of functions, they bring serious security and privacy problems. The third-party libraries and the host Apps run in the same process and share the same permissions.

How do you find unused resources?

You can easily search for unused resources from Android Studio. Just press Ctrl Alt Shift i and type "unused resources" (without quotes). That will execute lint.


2 Answers

This answer is summarized from Removing Unused Resources which explains how to use minifyEnabled and shrinkResources, which are covered in more depth at the Official document page.

It’s a common problem for third-party libraries to include assets that your application codepath does not use, and it’s critically important to remove those assets in order to produce smaller APK files for your users. Thankfully, the latest version of Gradle and Android Studio provides a solution to help.

By setting minifyEnabled and shrinkResources to true in your Gradle configuration, the system will go forth removing unused resources from your application.

android {     ...      buildTypes {         release {             minifyEnabled true             shrinkResources true             proguardFiles getDefaultProguardFile('proguard-android.txt'),                          'proguard-rules.pro'         }     } } 

It is important to note that removing unused resources requires the minifyEnabled flag to be set. This flag (as mentioned in Removing unused code) will trigger ProGuard to remove code paths that aren’t being used by your application. This is an important step in the removal of resources from included libraries. If the code paths aren’t removed, then the compiler will still believe the resources are referenced by an existing codepath and won’t remove them properly.

It's worth noting that this is a pretty extensive system. For instance, it will look through specific string constants in your code, as well as various res/raw resources looking for any URLs in the form of file:///…. to keep. It will even go so far as to analyze CSS, HTML, and JavaScript files as well.

Now, there may be instances here of false positives or false negatives. Assets might be getting cut, or kept, when you want the opposite behavior. (To be fair, resource shrinking tends to be overeager...) To adjust this, you can add the tools:keep and tools:discard attributes to define the desired behavior, by convention in a res/raw/keep.xml file.

<resources xmlns:tools="http://schemas.android.com/tools"      tools:keep= "@layout/l_used*_c,  @layout/l_used_b*"      tools:discard="@layout/unused2" /> 
like image 190
Colt McAnlis Avatar answered Sep 29 '22 23:09

Colt McAnlis


If you can't use shrinkResources for some reasons, at the least we can use resConfig to remove languages we don't support.

defaultConfig {     resConfig "en"      } 
like image 20
Riyaz Mohammed Ibrahim Avatar answered Sep 30 '22 00:09

Riyaz Mohammed Ibrahim