前语
代码稠浊关于每个入门的 Android 工程师来说都不会太生疏,因为在编译正式版别时,这是一个必不可少的进程。而且运用代码稠浊也恰当简略,简略到只需求装备一句minifgradle是什么yEnabljvm内存结构ed true
。可是你是否了解稠浊的原理,假定问你代码稠浊究竟做了什么,你会怎么说?
目录
1. 稠浊编译器
假定以稠浊编译器来区其他话,Android 代码稠浊能够分为以下两个时期:
- ProGuard:一个通用的 Java 字节码优化东西,由比利时团队 GuardSquare 开发
- R8:ProGuard 的继承者,专jvm调优参数为 Android 规划,编译功用和编译产品更优异
下图梳理了它们跟着 Android Gradle Plugin 版别迭代相应做出的改动:
其间,稠浊编译器的改动:
- 远古: ProGuard
- 3.2.0:ProGuardgradle版别(默许),R8(引进)
- 3.4.0:R8(approve默许)
其间:DE架构图怎么做X编译器的改动:
- 远古: DX
- 3.0.0:DX(默许),D8(引进)
- 3.1.0:D8(默许)
假定需求批改 Androidgradle翻译 Gradle Plugin 的默许行为,能够在gradle.properties
中增加装备:
- 启用与禁用 R8
# 显式启用 R8 android.enableR8 = true
#架构师薪酬一月多少 1. 只对 Android Library module 停用 R8 编译器 android.enableR8.libraries = false # 2. 对全部 module 停用 R8 编译器 android.enableR8 = false
- 启用与产品禁用 D8
#产品营销策划 显式启用 D8 android.enableD8 = true
# 显式禁用 D8 android.enableDapprove8 = false
其他,假定在运用模块的 buigradle下载慢解决方法ld.gradlappeare
文件中设置useProguard = false
,也会运用 R8 编译器代替 Pro架构中考Guard。
2. 四大功用
ProGgradle打包uard 与 R8 都提供了紧缩(shrinker)、优化(optimizer)、稠浊(架构图怎么做obfuscator)、预校gradle打包验(preverifier)四大功用:
-
紧缩(也称为摇树优化,tree shaking):从 运用及架构规划依托项 中移除 未运用 的类、方法和字段,有gradle教程助于逃避 64 方法数的瓶颈
-
优化:通过代码 分析 移除更多未运用的代码,甚架构是什么意思至重写代码
-
稠浊:运用无意义的简略称号 重命名 类/方法/字段,增加逆向难度
-
预校验:关于面向 Java 6 或许 Java 7 JVM 的 class 文件,编译时能够把 预校验信息 增加到类文件中(StackMap 和 StackMapTable特征),然后加速类加载功率。预校验关于 Java 7 JVM 来说是有必要的,可是关于 Android 平台 无效
运用 ProGuard 时,部分编译流程如下图所示:
- ProGuard 对 .c产品经理lass 文件实施代码紧缩、优化与稠浊
- D8jvm内存结构 编译器实施脱糖,并将 .class 文件转换为 .dex文件
运用 R8 时,部分编译流程如下图所示:
- R8 将脱糖(Desugar)、紧缩、优化、稠浊和 dex(D8 编译器)整合到一个进程
- R8 对 .class 文件实施代码紧缩appearance、优化与稠浊
- D8 编译器架构是什么意思实施脱糖,并将 .class 文件转换为 .applicationdex文件
对比JVM以下 ProGuard 与 R8 :
- 共同点:
1、开源
2、R8 支撑全部现有 ProGgradle教程uard 规产品运营则文件
3、都提供了四大appleid功用:紧缩、优化、稠浊、预校验
- 不同点:
1、ProGuard 可用于 Java 项目,而 R8 专为 Android 项目规划
2、R8 将脱糖(D产品质量法esugar)、紧缩、优化、稠浊和 dex(D8 编译器)产品营销策划整合到一个进程中,显jvm是什么意思着提高了编译功用
关于 D8 编译器
将 .class 字节码转化为 .dex 字节码的进jvm调优面试题程被架构师薪酬一月多少称为 DEX 编译,初步是由DX 编译器完毕。与 DX 编译器比较,新的 D8 编译器的编译速度 更快,输出的 .dex 文件 更小 ,却能坚持相同甚至 更超卓 的运用作业时功用
3. 运用示例
不管运用 R8 仍是 ProGuard,架构是什么意思默许不会启用紧缩、优化和稠浊功用。 这个规划首要是出于两方面考虑:一方面是因为这些编译jvm调优面试题时使命会增加编译产品规划时刻,另一方面是因为假定没有充分定义稠浊gradle版别保存规矩,还可能会引进作业时过失。因此,最好 只在运用的查验版别和发布版别中启用这些编译时使命架构,参看运用示例:
// build.gradle
...
android架构图模板 {
buildTypes {
// 查验版别
preview {
// 启用代码紧缩、优化和稠浊(由R8或许ProGuard实施)
minifyEnabled true
// 启用资源紧缩(由Android Gradle plugin实施gradle)
shrinkResources true
// 指定稠浊保存规矩文件
proguardFiles getDefaultProgujvm内存结构ardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
// 发布版别
release {
minifyEnabledapprove true
shrinkResources true
pgradle翻译roguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
// 开发版别
debgradle翻译ug{
minifyEnable产品生命周期d false
}
}
...
}
-
minifyEnabled
:(默许状况下)appearance启用代码紧缩、优化、稠浊与预校验 -
shringradle教程kResources
:启用资源紧缩 -
proguardFilappstorees
、prjvm类加载机制oguardFile
:指定 ProGuard 规矩文件,前者能够指定多个参数。下面两段装备的作用是相同的。// 方法一: proguardFiles getDefaultProgjvm调优面试题uardFile('proguard-andrappreciateoid-gradle教程optimize.txt'), 'progua架构是什么意思rd-rules.pro' // 方法二: proguardFile getDefaultProguardFile('proguard-android架构-opt架构师和程序员的差异imize.txt') proguardFile 'proguard-rulesappearance.pro'
前面说到了:不管运用R8仍是ProGuard,紧缩、优化和稠浊功用都是 默许封闭的。通过以下装备能够灵活操控:
- 全体封闭
minifyEnabled false
// 这行就没有作用了
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.proapple'
- 关jvm类加载机制闭紧缩
-dapplicationontshrink
- 封闭优化(R8 无效)
-dontoptimize
留神:R8gradle装备 不能封闭优化,也不允许批改优化的行为,事实上,R8 会疏忽批改默许优化行为的规矩。例如设置 -ogradle装备ptimizations
和 -optimizationpasses
后会得到编译时正告:
AGPBI: {"kind":"warning","text":"Ignoring产品 option: -optimizations","source产品运营首要做什么s":[{"file":"省掉..."}],"tool":"D8"}
AGPBI: {"kind":"w产品运营首要做什么arning","text":"Ig产品规划专业noring option: -optimizationpasses","sources"jvm内存模型:"省掉..."}],"tool":"D8"}
- 封闭稠浊(主张在开发版别封闭稠浊)
-dontobfuscate
- 封闭预校验(对 Android 平台无效,主张封闭)
-dontpreverify
4. ProGuard 规矩文件
R8 连续了 ProGuard 运用规矩文件批改默架构图模板许行为的做法。在许多时候,规矩文件也被称为稠架构是什么意思浊保存规矩文件,这是因为该文件内定义的绝大多数规矩都是和代码稠浊相关的。事实上,文件内还能够定义代码紧缩、优化和预校验规矩,因此称为 ProGuard 规矩文件比较慎重。
在上一节里,咱们说到了运用proguardFiles
和proguardFile
指定 ProGuard 规矩文件。关于任何一个项目,它的 ProGu产品ard 规矩文件有以下三种来历:
- 1、Android Gradle 插件
在编译时,Android Gradle 插件会生成proguard-android-optimize.txt
、proguard-android.txt
,方位在<module-dir>/build/intermediatjvm调优参数egradle homes/proguard-files/
。这两个文件中除了注释之外,仅有的差异是前者apple启用了如下代码紧缩,而后者封闭了代码紧缩,如下所示:
# proguard-android-optimize.txt
-optimizations !code/simplificatijvm调优参数on/arithmetic,!code/sjvm是什么意思implification/cast,!field/*,!class/merging/*
-optimizationpasses 5
-allowaccessmodification
相同部分省掉...
# proguard-android.txAPPt
-dontoptimize
相同部分省掉...
其间相同的架构规划那部分稠浊规矩中,下面这一部分是比较特其他:
-keep产品生命周期 class androidjvm内存结构.supporgradle打包t.annotation.Keep
-keep class androidx.annotation.Keep
// 保产品存@gradle打包Keep注解的类,保存...TODO
-keep @android.架构support.annotation.Keep class * {*;}
-keep @androidx.annotation.Keep class *jvm调优参数 {*;}
// 保存@Keep修饰的方法
-keepclasseswithmembersgradle class * {
@android.support.annotatapproachion.Keep <methods>;
}
-keepclasseswithmembers class * {
@androidx.annotation.Keep <methods&jvm内存模型gt;;
}
// 保存@Keep修饰的字段
-keepclasseswithmembers class * {
@android.support.annotation.Keep <fields>;
}
-keepclasseswithmembers class * {
@androidx.annotation.Keep <fields>;
}
// 保存@Keep修饰的结构方法
-keejvm是什么意思pclasseswit架构师薪酬一月多少hmembers class * {
@android.support.annotation.Keep <init>(.gradle教程..);
}
-keepcla产品sseswithmembers class * {
@androidx.annotation.Keep <init>(...);
}
它指定了与@Keep
注解相关的全部保存规矩,这儿就解释了为什么运用@Keep
修饰的成员不会被稠浊了吧?
- 2、Android AsAPPset Package Tool 2 (AAPT2)
在编译时,AAPT2 会依据对 Manifest 中的类、布局及其他运用资源的引证来生成aapt_rules.txt
,方位在&approvelt;module-dijvm参数r>/build/intermediates/proguard-rules/debug/架构师aapt_rules.txt
。
例如,AAPT2 会为 Manifest 中注册的每个组件增加保存规矩:
Referenced at [项目途径]/app/build/intermediatesjvm参数/merged_manifests/release/AndroidManifest.xml:19
-jvm废物回收机制keep class com.have.a.good.time.MainActivity { <init>(); }
省掉...
在这儿,AAPT2 生成了Main架构中考Activity
的保存规矩,一同它还指出了引证出处:AndroidManifest.xml:19
。这是因为 发起 Activity 的进程中,需求运用反射的方法实例化具体的每一个 Activity ,有爱gradle教程好jvm是什么意思能够看下 ActivityThread#performLau产品密钥在哪里能找到nchActivity()
-> Iappreciatenstrumentation#newActivity(jvm调优参数)
- 3、Module
创建新 Mjvm是什么意思odule 时,IDE 会在该模块的根目录中创建一个proguard-rules.applicationpro
文件。当然,除了这个主动生成的文件,还可APP以按需创建额定的规矩文件。例如,下面的装备对 releappearase 增加了额定的规矩文件:
...
android {
...
buildTypes {
release {
mappleidinifyEnabled true
proguardFile产品生命周期s getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
productFlavors {
dev{
...
}
release{产品营销策划
proguardFile 'gradle装备release-rules.pro'
}
}
}
...
小结一下:
规矩文件来历 | 描绘 |
---|---|
Android Gradle 插件 | 在编译时,由 Android Gradle 插件生成 |
AAPT2 | 在编译时,AAPTapprove2 依据对运用清单中的类、布局及其他运用资源的引证来生成保存规矩 |
Module | 创建新 Mod架构师薪酬一月多少ule 时,由 IDE 创建,或许其他按需创建 |
假定将minigradle下载慢解决方法fyEnabled
特征设为tgradle翻译rue
,ProGuard 或 R8 会将来自上面列出的全部可用来历的规矩组合在一同。为了看到无缺的规矩文件,能够在proguard-rules.pro
中增加以下装备,输出编译项目时运用的全部规矩的无缺陈述:
-prin架构师tconfiguration产品 build/intermediates/proguard-files/full-config.gradle是什么txt
5. 组件化稠浊
在组件化的项目中,需求留神运用 Module 和 Library Module 的行为差异和组件化的资源调集规矩,总结为以下几个要害:
- 编译时会依次对各层 Library Module进行编译,最底层的 Base Module 会最先被编译为 aar 文件,然后上一层编译时会将依托 Module 输出的 aar 文件/ jar 文件解压到模块的 build 中相应的文件夹中
- App Module 这一层汇总了全部的 aar 文件后,才真正初步编译操作
- 后jvm调优编译的 MoAPPdule 会掩盖之前编译的 Module 中的同名资源
运用产品运营首要做什么较高版其他 Android Gradle Plugin,jvm调优面试题不会将汇总的资源放置在 exploded-aar
文件夹。即便如此,Lib Module 的资源汇总到 App Module 的规矩是相同的。
咱们通过一个简略示例查验不同装备下的稠jvm参数浊作用:
装备一 | 装备二 | 装备三 | 装备四 | |
---|---|---|---|---|
App Module 翻开稠浊 | X | X | √ | √ |
Base Mod架构图怎么做ule 翻开稠浊 | X | √ | X | √ |
将构建jvm是什么意思的 apk 包拖到 Android Studio 面板上即可分析 Base 类稠浊作用,例如装备一的作用:
全部查验作用如下:
装备一 | 装备二 | 装备三 | 装备四 | |
---|---|---|---|---|
Ap架构师p Module 翻开稠浊 | X | X | √ | √ |
Base Module 翻开稠浊gradle发音 | X | √ | X | √ |
(作用)Base 类是否被稠浊 | X | X | √appear | √ |
能够看到,稠浊翻开由 App Module 抉择, 与Lib Module 无关。
现在咱们分别在 Lib Module 和 App Module 的 proguard-rules.pro
中增加 Base 类的稠浊保存规矩,并在 build.gradle
中增加装备文件,查验 Base 类是否能保存:
-keep class com.rui.base.Base
查验作用如下:
装备方位 | Lib Module | App Module |
---|---|---|
(作用)Base 类是否保存 | X | √ |
能够看到:(默许状况)稠浊规矩以 App Module 中的稠浊规矩文件为准。
这儿就引进两种干流的组件化approve稠浊计划:
- 在 App Module 中设置稠浊产品规划专业规矩
这种计划将稠浊规矩都放置到 App Module 的proguard-ruljvm调优面试题es.pro
中gradle下载慢解决方法,最简略也最直观,缺陷是移除 Lib Module 时,需求从 App Module 中移除相应的稠浊jvm内存模型规矩。尽管剩余的稠浊规矩并不会构成编译过失或许作业过失,但仍是会影响编译功率。
许多的第三方 SDK,就是采用了这种组件化稠浊计划。在 App Module 中增加依托的一同,也需求在proguard-rules.pro
中增加专属jvm废物回收机制的稠浊规矩,这样才华确保releasegradle打包
版别正常作业。
- 在 App Module 中设置公共稠浊规矩,在 Lib Module 中设置专属稠浊规矩
这种计划将专属的产品生命周期稠浊规矩设置到 Lib Module 的prjvm类加载机制og架构师薪酬一月多少uard-rules.pro
,可是依据前面的查验,在 Lib Module 中设置的稠浊规矩是不收效的。为了让规矩收效,还需求在 Lib Module 的build.gradle
中增加以下装备:gradle是什么
...
android{
defaultConfig{
consumerProguardFiles 'consumer-rules.pro'
}
}
其间consumer-rules.pro
文件:
-keep class com.applicationrui.base.Base
查验作用标明,Base 类现已被保存了。这种运用产品营销策划consumerProguardFiles
的办gradle打包法有产品生命周期以下几个特征:
-
consumerProguardFiles
只对 Lib Module 收效,对 App Module 无效 -
consumerProguardFiles
会将稠浊规矩输出为prappearanceoguard.txt
文件,并打包进 a产品密钥在哪里能找到ar 文件 - App Module 会运用 aar 文件中的
proguard.txt产品运营首要做什么
汇总为究竟的稠浊规矩,这一点能够通过前面说到的-printconfiguration
证明
6. 总结产品运营
-
Pgradle下载roGuard 是 Java 字节码优化东西,而 R8 是专为 Android 规划的,编译功用和编译产产品品更优异;
-
ProGuard 与 R8 都提供了四大功用:紧jvm废物回收机制缩、优化、稠浊和预校验。ProGuardjvm参数 首要是对 .class 文件实施代码紧缩、优化与稠浊,再由 D8 编译器实施脱糖并转换为 .dex 文件。R8 将紧缩、优化、稠浊、脱糖和 dex 整合为一个进程;
-
ProGuard 规矩文件有jvm参数三种来历:gradle是什么Android Gradle 插件、AAPT2、Module;
-
默许状况下,稠浊规矩以 App Module 中的稠浊规矩gradle发音文件为准,运用 consumer-rules.pro 文件能够设置 Lib Module 专属稠浊规矩。
参看资料
- 紧缩您的运用
- ProGuarjvm调优d |产品规划专业 Office website
- ProGuard | Manual
- R8 | Google Git
- Android Gradle plugin release njvm内存模型otes
- 《深化了解Java虚拟机 — JVM高appearance级特性与最佳实践》 周志明 著
- 《Android 组件架构中考化架构》 仓王 著
- 《jvm内存结构Androidgradle下载开发高手课》 张绍文 著,极客时刻 出品
创造不易,你的「三连」是丑丑最大approach的动力,咱们下次见!