Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
849 views
in Technique[技术] by (71.8m points)

performance - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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"
/>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...