2015-10-13 49 views
61

我链接到我的应用程序的第三方库通常包含未被我的应用程序使用的资源文件,因此最终导致我的APK膨胀。如何从Android上包含的第三方库中删除未使用的资源?

例如,包括Google Play服务库,但未使用登录按钮功能;所有这些图像和布局资源都会在我的最终构建中结束。

由于这些资源包含在已编译的库中,因此如何从构建中删除它们?

回答

69

这个答案是从Removing Unused Resources这也解释了如何使用minifyEnabled和shrinkResources,这是在Official document page覆盖更深入总结。

第三方库包含应用程序代码路径未使用的资产是一个常见问题,为了为用户生成更小的APK文件,删除这些资产非常重要。谢天谢地,最新版本的Gradle和Android Studio提供了一个解决方案来帮助。

通过设置minifyEnabledshrinkResources到真正在你的摇篮配置,系统将出去,从你的应用程序删除未使用的资源。

android { 
    ... 

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

重要的是要注意,删除未使用的资源需要minifyEnabled标志设置是非常重要的。此标志(如Removing unused code中所述)将触发ProGuard删除未被应用程序使用的代码路径。这是从包含的库中删除资源的重要步骤。如果代码路径没有被删除,那么编译器仍然会认为资源被现有代码路径引用,并且不会正确删除它们。

值得注意的是,这是一个相当广泛的系统。例如,它会查看代码中特定的字符串常量,以及查找以file:///….形式保留的任何URL的各种res/raw资源。它甚至可以分析CSS,HTML和JavaScript文件。

现在,可能会出现假阳性或假阴性的情况。当你想要相反的行为时,资产可能会被削减或保留。 (公平地说,资源收缩趋于过份...)为了调整这一点,您可以添加工具:保留工具:放弃属性以按照约定在res/raw/keep.xml文件中定义所需的行为。

<resources xmlns:tools="http://schemas.android.com/tools" 
    tools:keep= "@layout/l_used*_c, @layout/l_used_b*" 
    tools:discard="@layout/unused2" 
/> 
+0

对于那些使用retrolambda的人 - 如果资源中引用了lambda表达式所使用的资源 - 资源将被删除,因此它将制动构建。所以,现在shrinkResources必须设置为false,即使对于发布变体 – curioushikhov

+0

@Colt McAnlis是否也会删除未使用的语言?我们可以在defaultConfig中使用resConfigs“en”来删除未使用的语言。 –

8

如果您不能使用shrinkResources出于某些原因,在至少我们可以用resConfig删除我们不支持的语言。

defaultConfig { 
    resConfig "en"  
} 
+1

即使您使用shrinkResources,也可以添加resConfig网络来降低apk大小。 –

+0

添加resConfig会打破APK SPLITS ... – slott

相关问题