Gralde学习笔记--提升构建速度和项目优化

这一节会介绍之前没提到的构建技巧和提示,包括

  1. 减少apk大小
  2. 加快构建速度
  3. 忽略Lint检查
  4. 使用Ant工具
  5. 改进app部署

1.减小apk文件大小(Reducing APK file size)

1.1 ProGuard

ProGuard是一个java工具,不仅可以收缩代码,还能优化,混淆代码和编译阶段验证代码,他会查找所有并删除未使用的代码,也会重命名类和属性,让app难以被反编译。android插件有个属性minifyEnabled在build.gradle中,就是设置是否开启ProGuard功能。

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

如果设置为true,progrardRelease task就会在构建过程调用ProGuard。

最好设置后重新测试下app,因为他有可能会造成需要的代码丢失,为了解决这个问题,可以定义ProGuard规则去排除一些类避免被移除或者混淆,proguardFiles属性就是定义规则文件的。比如,保留一个类,在规则文件中这么写

-keep public class <MyClass>

getDefaultProguardFile(‘proguard-android.txt’)方法从proguard-android.txt文件中获取默认ProGuard设置,这个文件来自Android SDK的tools/proguard文件夹。proguard-rules.pro文件会被AS默认添加到新的module中,可以在这里添加新的规则,每个项目的规则都不太一样,具体要看引入的库和自己写的代码,学习ProGuard和ProGuard rules,参见文件

除了压缩java代码,还有一个好办法是压缩资源文件

1.2 压缩资源文件(Shrinking resources)

gradle可以在构建阶段去掉未使用的资源,这在你有很多老的资源忘记移除,或者有一个库有很多资源,但是你只想用很少一部分,就可以开启资源压缩。有2个方法,自动的和手动的

1.2.1 自动压缩
android {
    buildTypes {
        release {
            minifyEnabled = true
            shrinkResources = true
        }
    }
}

最简单的就是配置shrinkResources,就可以自动压缩,但是最好把minifyEnabled也开启,因为资源压缩需要依靠哪些资源未被代码引用才去移除,如果没有压缩代码,可能哪些无用的代码在引用资源,导致本来无用资源也没被移除

如果想明确的看压缩后小了多少,可以运行shrinkReleaseResources task,将打印出包大小减少了多少

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

如果想看到详细的哪些资源被移除,添加–info

$ gradle clean assembleRelease --info

他将打印出关于哪些资源未被加入到apk的额外信息

自动压缩有个问题就是,它可能会移除过多的资源,特别是动态使用的可能会被意外移除,为了避免这个情况,可以定义哪些资源需要保留在keep.xml中,这个文件放在res/raw/下去创建,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_*"
/>

1.2.2 手动压缩(Manual shrinking)
平和一点的方式是移除某些语言文件或者某些密度的图片文件。一些库,比如Google Play Services,包含了大量语言文件,我们的app可能只需要1到2种语言,这样就很浪费,可以使用resConfigs属性配置要保留的资源,剩余的会被扔掉。

如果你只想要English,Danish和Dutch

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

也可以定义密度

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

你甚至可以组合配置语言和密度,每一种资源都可以通过这个属性进行限制

NOTE: 在配置中写的会保留,其他的都会被抛弃(不会被打包到apk)

2.提升构建速度(Speeding up builds)

很多开发者抱怨编译时间太长。由于gradle整个生命周期有3个阶段,每次运行task都要经历,这使得整个过程都可配置,但是也变得很慢。幸运的是,有一些方法去提高构建速度

2.1 Gradle属性(Gradle properties)

一个微调构建速度的方法是改变一些默认设置,在第5章提到了并行构建,但还有更多设置我们可以调整

开启并行构建,在gradle.properties文件配置

org.gradle.parallel=true

另一个是开启Gradle daemon,这会开启一个后台进程在你第一次运行构建程序,任何后面的子构建都会复用整个进程,避免了重启的开销。这个进程在运行gradle时一直存活,空闲3小时后才挂掉,在你短时间多次使用gradle时候效果很好,同样在gradle.properties

org.gradle.daemon=true

在AS中daemon默认开启,意味着在IDE中第一次构建后,后面的构建都会快一点,如果是命令行构建就不行,除非定义了属性在文件中,像上面那样

提升自己的编译速度,可以微调虚拟机参数,比如,jvmargs属性,可以设定不同值的内存大小给jvm。-Xms设置初始大小,-Xmx指定最大内存,同样在gradle.properties配置

//大小单位k(kb)  m(mb)  g(gb)
org.gradle.jvmargs=-Xms256m -Xmx1024m

要看自己电脑的能力设置大小

最后一个能影响构建速度的可配置属性是org.gradle.configureondemand,这个属性在你的项目有很多module时候很有用,他会尝试限制在配置阶段消耗的时间,会跳过正在执行的task不需要的module,如果设置为true,gradle会尝试在配置阶段前计算出哪些modules有配置变化,哪些没有。如果项目只有一个app和一个库,这个属性就没啥用了

如果想在所有项目应用这些配置,可以在.gradle文件夹下创建gradle.properties文件,.gradle一般在c盘用户目录下(windows系统)

2.2 Android Studio

在as中也可以配置这些属性,在settings中的compiler选项

2.3 Profiling

如果想知道哪些部分降低了构建速度,可以在执行任何task时候后面加上–profile标志,这样会在module的build/reports/profile下面生成html形式的报告,告诉你哪些过程时最消耗时间的,比如

gradle clean --profile

2.4 Jack和Jill
如果想体验实验性的工具,可以开启Jack和Jill提升构建速度,Jack是益虫新的构建工具链,可以把java文件直接转换成dex格式,他有自己的.jack库来打包和压缩。Jill是一个把.aar和.jar文件转换成.jack库的工具,他们还出一实验性阶段,但是可以提升构建速度和简化构建流程,但是不建议在正式项目使用,为了开启这个,需要构建工具版本21.1.1或更高

android {
    buildToolsRevision '22.0.1'
    defaultConfig {
        useJack = true  
    }
}

也可以指定他俩在某些build type或者product flavor上开启,这个方式,我们可以同时继续使用常规构建工具

android {
    productFlavors {
        regular {
            useJack = false
        }
        experimental {
            useJack = true
        }
    }
}

设置useJack为true,压缩和混淆就不再通过ProGuard执行了。但是仍然可以使用ProGuard规则语法指定规则和例外(也就是资源保留)

3.忽略lint(Ignoring Lint)

在运行发布构建时候,静态代码分析工具Lint就会执行,标记出潜在的布局或代码错误,某些时候,这样会阻塞构建过程,忽略Lint错误可以避免终止构建,但是这只应该用在一些临时情况,不然构建虽然完了,但是有可能有些错误存在,配置如下

android {
    lintOptions {
        abortOnError false
    }
}

猜你喜欢

转载自blog.csdn.net/One_Month/article/details/88124991