Gradle配置详解系列(五)-- apk瘦身配置

261 阅读4分钟
引言

随着业务的复杂度增加,也伴随着引入的第三方库的数量增加, 导致apk的体积也越来越大,越来越臃肿,所以apk瘦身就必须提上日程, 下面我们来总结下使用gradle 配置如何进行apk瘦身。

1. 自动清理掉未使用资源Resource Shrinking

他是一种在构建时,打包成Apk之前,会检测所有资源,看看是否被引用, 如果没有,那么这些资源就不会被打包到Apk包中.因为是在这个过程中(构建时),Android Gradle构建系统会拿到所有的资源,不管是你项目自己的, 还是引用的第三方的,它都一视同仁的处理,所以这个时机点可以控制哪些资源可以被打包,所以能解决第三方不使用的资源的问题。Resource Shrinking要结合着Code Shrinking一起使用,什么是Code Shrinking呢?就是我们经常使用的ProGuard,也就是我们要启用minifyEnabled,是为了缩减代码的。

android {

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

我们运行./gradlew :app:assembleRelease 就可以看到如下日志:

 :app:transformClassesWithDexForRelease
 :app:transformClassesWithShrinkResForRelease
 Removed unused resources: Binary resource data reduced from 220KB to 129KB: Removed 41%
 Note: If necessary, you can disable resource shrinking by adding

如果你想看详细日志,想知道哪些资源被自动清理了, 可以使用–info标记,显示详细的Gradle信息,然后把和自动清理资源的日志过滤出来即可。 我们可以通过如下命令实现:

 ./gradlew clean :app:assembleRelease --info | grep "unused resource"

运行后我们可以通过日志输出看到具体的哪些资源被清理了:

 Skipped unused resource res/drawable/unusedlogo.jpg: 910005 bytes (replaced with small dummy file of size 0 bytes)
 Removed unused resources: Binary resource data reduced from 220KB to 129KB: Removed 41%

注意:自动清理未使用的资源这个功能虽好,但是有时候会误删,为什么呢,因为我们在代码编写的时候可能会使用反射去引用资源文件, 尤其很多你引用的第三方库会这么做,这时候Android Gradle就区分不出来了, 可能会误认为这些资源没有被使用。 针对这中情况,Android Gradle为我们提供了keep方法来让我们配置哪些资源不被清理。 keep方法使用非常简单,我们要新建一个xml文件来配置,这个文件是 res/raw/keep.xml, 然后通过tools:keep属性来配置,这个tools:keep接受一个以逗号(,)分割的配置资源列表, 并且支持星号(*)通配符。 对于res/raw/keep.xml这个文件我们不用担心,Android Gradle构建系统最终打包的时候会清理它, 不会把它打包进Apk中的,除非你在代码中通过R.raw.keep引用了它。

 <?xml version="1.0" encoding="utf-8"?>
 <resources xmlns:tools="http://schemas.android.com/tools" 
  tools:keep="@layout/lay_u*_iii,@layout/lay_u_i,@layout/lay_u_ii*"/>
2. 手动配置 resConfigs

resConfigs,它属于ProductFlavor的一个方法,可以让我们配置哪些类型的资源才被打包到Apk中, 比如只有中文的,只有hdpi格式的图片等等,这是非常重要的, 比如我们引用的第三方库,为了更好适配国际化,可能支持了几十种语言, 但是对于我们的App来说,我们并不需要这么多,比如我们只用中文的语言就可以了, 其他的都不需要;比如我们支持xhdpi格式的图片就好了,其他的都不需要, 这时候我们就可以通过resConfigs方法来配置 :

  android {
      ...
      defaultConfig {
          ... 
          resConfigs 'zh'
        //resConfigs 'zh','xhdpi'
      }
  }

 

事实上,每种类型的资源都可以使用此属性进行限制。

以上清理资源只是在打包的时候,不打包到Apk中,实际上并没有删除我们工程中的资源,如果我们在使用的时候发现有大量的无用资源被清理, 那么我们自己最好还是把这些资源文件从我们的工程中删除,这样也更好维护一些。

更多Android技术分享可以关注我的Android技术圈子添码猩球, 也可以加入QQ群号:690347536,学习交流Android开发技能。