zoukankan      html  css  js  c++  java
  • 通过Gradle为APK瘦身

    引言:在过去几年中,APK 文件的大小曾急剧增长态势。一般来说,其原因如下:Android开发者获取了更多的依赖库,添加了更多的密度,Apps 增加了更多的功能。但实际上我们应该让APKs 尽可能的小,更小的APK 意味着用户可以更快地下载和安装应用,并使它占用更小的内存。 
    本文选自《Gradle for Android 中文版》,将研究如何设置Gradle 构建配置文件中的几个属性,以缩小APK 文件。

    ProGuard

      ProGuard 是一个Java 工具,其不仅可以缩减APK 文件大小,还可以在编译期优化、混淆和预校验你的代码。其通过你应用的所有代码路径,来找到未被使用的代码,并将其删除。 
      ProGuard 还会重命名你的类和字段。这一过程将保留应用的踪迹,让反编译工程师更加难以读懂代码。 
      在Gradle 的Android 插件中,其构建类型下面有一个叫作minifyEnabled 的布尔类型属性,你需要将它设置为true 来激活ProGuard :

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

      当minifyEnabled 被设置为true 后,在构建过程中,proguardRelease task 会被执行,并调用ProGuard。 
      在激活ProGuard 之后,应重新测试整个应用,因为ProGuard 可能会移除一些你仍需要使用的代码。这也是很多开发者不喜欢ProGuard 的原因。为了解决这个问题,你可以定义ProGuard 规则,排除那些被删除或混淆的类。我们可以使用proguardFiles 属性来定义包含ProGuard 规则的文件。例如,为了保留一个类,你可以像下面这样添加一条简单的规则:

    -keep public class <MyClass>

      getDefaultProguardFile(‘proguard-android.txt’) 方法从Android SDK 的tools/proguard 文件夹下的proguard-android.txt 文件中获取默认的ProGuard 设置。 
      在Android Studio 中,proguard-rules.pro 文件被默认添加到新的Android 模块,所以你可以在该文件中简单地添加一些针对该模块的规则。

    提示:你构建的每个应用或依赖库都有不同的ProGuard 规则,所以在本书中,我们不会考虑更多的细节。如果你想了解更多关于ProGuard和ProGuard规则的信息,则可以通过http://developer.android.com/tools/help/proguard.html. 来查阅AndroidProGuard 的官方文档。除了缩减Java 代码外,还可以缩减使用过的资源。

    缩减资源

      当给App 打包时,Gradle 和Gradle 的Android 插件可以在构建期间删除所有未使用的资源。如果你有旧的资源忘记删除,那么这个功能可能非常有用。另外一个使用案例是当你导入一个拥有很多资源的依赖库,而你只使用了其中的一小部分时,你可以通过激活缩减资源来解决这个问题。缩减资源的方式有两种:自动和手动。

    自动缩减

      最简单的方式是在你的构建中设置shrinkResources 属性。如果设置该属性为true,则Android 构建工具将自动判定哪些资源没有被使用,并将它们排除在APK 外。使用此功能有一个要求,即必须同时启动ProGuard。这是因为缩减资源的工作方式是,直到代码引用这些资源被删除之前,Android 构建工具不能指出哪些资源没有被用到。 
      下面的代码片段展示了在某个构建类型中,如何配置自动化资源缩减:

    android {
           buildTypes {
           release {
                 minifyEnabled = true
                 shrinkResources = true
                 }
           }
    }

      如果你想看看在激活了自动化资源缩减之后,APK 缩减了多少,则可以运行shrink-ReleaseResources 任务。该任务会打印出包的大小缩小了多少:

    :app:shrinkReleaseResources
    Removed unused resources: Binary resource data reduced from 433KB
    to 354KB: Removed 18%

      你可以通过在构建命令中添加 –info 标志,来获得APK 缩减资源的概览:

    $ gradlew clean assembleRelease –nfo

      当你使用该标志时,Gradle 会打印出许多关于构建过程的额外信息,包括最终构建不会输出的每个资源。 
      自动资源缩减有一个问题,即它可能移除了过多的资源,特别是那些被动态使用的资源可能被意外删除。为了防止这种情况的发生,你可以在res/raw/ 下的一个叫作keep.xml的文件中定义这些例外。一个简单的keep.xml 文件如下所示:

    <?xml version="1.0" encoding="utf-8"?>
    <resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@layout/keep_me,@layout/also_used_*"/>

      keep.xml 文件自身也将从最终的结果中被剥离出来。

    手动缩减

      去除某种语言文件或某个密度的图片,是删减资源的一种比较好的方式。一些依赖库,例如Google Play Services,其包含了多种语言。如果你的应用只支持一两种语言,那么在最终的APK 中,包含所有语言的文件就会浪费许多资源。这时你就可以使用resConfigs 属性来配置你想保留的资源,将其余部分删除。 
      如果你只想保留英语、丹麦语和荷兰语的字符串,则可以这样使用resConfigs :

    android {
        defaultConfig {
              resConfigs “en", “da", “nl"
        }
    }

      你也可以这样处理密度集合:

    android {
        defaultConfig {
              resConfigs “hdpi", “xhdpi", “xxhdpi", “xxxhdpi"
        }
    }

      你甚至可以结合语言和密度。实际上,使用此属性可以限制每一种类型的资源。 
      如果设置ProGuard 让你感觉很困难,或者你仅仅想在应用中去除不支持的语言资源或密度,那么你可以使用resConfigs 来缩减资源。 
      本文选自《Gradle for Android 中文版》,点此链接可在博文视点官网查看。 
                       图片描述

  • 相关阅读:
    观察者模式 java实现
    Decorator 模式
    Adapter 模式 java 实现
    Singleton 模式 Java,c++实现
    抽象工厂 java实现
    工厂方法模式 java实现
    简单工厂模式 Java实现
    【4】学习JS 数据结构与算法笔记
    【3】JavaScript编程全解笔记(三)
    【3】如何高效学习笔记
  • 原文地址:https://www.cnblogs.com/broadview/p/6245834.html
Copyright © 2011-2022 走看看