2024年安卓最全深入学习-Gradle-自动化构建技术(一)Gradle-核心配置(1),2024年最新面试常识

尾声

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

最后想要拿高薪实现技术提升薪水得到质的飞跃。最快捷的方式,就是有人可以带着你一起分析,这样学习起来最为高效,所以为了大家能够顺利进阶中高级、架构师,我特地为大家准备了一套高手学习的源码和框架视频等精品Android架构师教程,保证你学了以后保证薪资上升一个台阶。

当你有了学习线路,学习哪些内容,也知道以后的路怎么走了,理论看多了总要实践的。

进阶学习视频

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

作者:jsonchao
链接:https://juejin.im/user/5a3ba9375188252bca050ade/posts

B站全套Android移动架构师进阶视频教程白嫖地址:https://space.bilibili.com/544650554

1、Gradle 是什么?

  • 1)、它是一款强大的构建工具,而不是语言。
  • 2)、它使用了 Groovy 这个语言,创造了一种 DSL,但它本身不是语言。

2、为什么使用 Gradle?

主要基于如下 三点 原因:

  • 1)、它是一个款最新的,功能最强大的构建工具,使用它我们能做很多事情。
  • 2)、使用程序替代传统的 XML 配置,使得项目构建更加灵活。
  • 3)、丰富的第三方插件,可以让我们随心所欲地使用。

3、Gradle 的构建流程

通常来说,Gradle 一次完整的构建过程通常分成如下 三个部分:

  • 初始化阶段:首先,在初始化阶段 Gradle 会决定哪些项目模块要参与构建,并且为每个项目模块创建一个与之对应的 Project 实例。
  • 配置阶段:然后,配置工程中每个项目的模块,并执行包含其中的配置脚本。
  • 任务执行:最后,执行每个参与构建过程的 Gradle task。

二、打包提速

掌握 Gradle 构建提速的技巧能够帮助我们节省大量的编译构建时间,并且,依赖模块越多且越大的项目节省出来的时间越多,因此是一件投入产出比相当大的事情。

1、升级最新的 Gradle 版本

将 Gradle 和 Android Gradle Plugin 的版本升至最新,所带来的的构建速度的提升效果是显而易见的,特别是当之前你所使用的版本很低的时候。

2、开启离线模式

打开 Android Studio 的离线模式后,所有的编译操作都会走本地缓存,毫无疑问,这将会极大地缩短编译时间。

3、配置 AS 的最大堆内存

在默认情况下, AS 的最大堆内存为 1960MB,我们可以选择 Help => Edit Custom VM Options,此时,会打开一个 studio.vmoptions 文件,我们将第二行的 -Xmx1960m 改为 -Xmx3g 即可将可用内存提升到 3GB

4、删除不必要的 Moudle 或合并部分 Module

过多的 Moudle 会使项目中 Module 的依赖关系变得复杂,Gradle 在编译构建的时候会去检测各个 Module 之间的依赖关系,然后,它会花费大量的构建时间帮我们梳理这些 Module 之间的依赖关系,以避免 Module 之间相互引用而带来的各种问题。除了删除不必要的 Moudle 或合并部分 Module 的方式外,我们也可以将稳定的底层 Module 打包成 aar,上传到公司的本地 Maven 仓库,通过远程方式依赖

5、删除Module中的无用文件

  • 1)、如果我们不需要写单元测试代码,可以直接删除 test 目录。
  • 2)、如果我们不需要写 UI 测试代码,也可以直接删除 androidTest 目录。
  • 3)、此外,如果 Moudle 中只有纯代码,可以直接删除 res 目录。

6、去除项目中的无用资源

在 Android Studio 中提供了供了自动检测失效文件和删除的功能,即 Remove Unused Resource 功能,操作路径如下所示:

右键 => 选中 Refactor => 选中Remove Unused Resource => 直接点击REFACTOR

需要注意的是,这里不需要将 Delete unused @id declarations too 选中,如果你使用了 databinding 的话,可能会编译失败

7、优化第三方库的使用

一般的优化步骤有如下 三步:

1)、使用更小的库去替换现有的同类型的三方库。

2)、使用 exclude 来排除三方库中某些不需要或者是重复的依赖。

例如,我在 Awesome-WanAndroid项目中就使用到了这种技巧,在依赖 LeakCanary 时,发现它包含有 support 包,因此,我们可以使用 exclude 将它排除掉,代码如下所示:

debugImplementation (rootProject.ext.dependencies[“leakcanary-android”]) {
exclude group: ‘com.android.support’
}
releaseImplementation (rootProject.ext.dependencies[“leakcanary-android-no-op”]) {
exclude group: ‘com.android.support’
}
testImplementation (rootProject.ext.dependencies[“leakcanary-android-no-op”]) {
exclude group: ‘com.android.support’
}

3)、使用 debugImplementation 来依赖仅在 debug 期间才会使用的库,如一些线下的性能检测工具。如下是一个示例代码:

// 仅在debug包启用BlockCanary进行卡顿监控和提示的话,可以这么用
debugImplementation ‘com.github.markzhai:blockcanary-android:1.5.0’

8、利用公司 Maven 仓库的本地缓存

当第一个开发引入了新库或者更新版本之后,公司的 Maven 仓库中就会缓存对应的库版本,通过这样的方式,其他开发同事就能够在项目构建时直接从公司的 Maven 仓库中拿到缓存。

9、Debug 构建时设置 minSdkVersion 为 21

这样,我们就可以避免因使用 MutliDex 而拖慢 build 速度。在主 Moudle 中的 build.gradle 中加入如下代码:

productFlavors {
speed {
minSdkVersion 21
}
}

同步项目之后,我们在Android Studio右侧的 Build Variants 中选中 speedDebug 选项即可,如下图所示:

需要注意的是,要注意我们当前项目的实际最低版本,比如它为 18,现在我们开启了 speedDebug,项目编写时就会以 21 为标准,此时,就 需要注意 18 ~ 21 之间的 API,例如我在布局中使用了 21 版本新出的 Material Design 的控件,此时就是没问题的,但实际我们需要对 21 版本以下的对应布局做相应的适配。

此外,我们也可以定义不同的 productFlavors,并且在 src 目录下新建对应的 flavor 名称标识的目录资源文件,以此实现在不同的渠道 APK 中采用不同的资源文件。

10、配置 gradle.properties

通用的配置项如下所示:

// 构建初始化需要执行许多任务,例如java虚拟机的启动,加载虚拟机环境,加载class文件等等,配置此项可以开启线程守护,并且仅仅第一次编译时会开启线程(Gradle 3.0版本以后默认支持)
org.gradle.daemon=true

// 配置编译时的虚拟机大小
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

// 开启并行编译,相当使用了多线程,仅仅适用于模块化项目(存在多个 Library 库工程依赖主工程)
org.gradle.parallel=true

// 最大的优势在于帮助多 Moudle 的工程提速,在编译多个 Module 相互依赖的项目时,Gradle 会按需选择进行编译,即仅仅编译相关的 Module
org.gradle.configureondemand=true

// 开启构建缓存,Gradle 3.5新的缓存机制,可以缓存所有任务的输出,
// 不同于buildCache仅仅缓存dex的外部libs,它可以复用
// 任何时候的构建缓存,设置包括其它分支的构建缓存
org.gradle.caching=true

这里效果比较好一点的配置项就是 配置编译时的虚拟机大小 这项,我们来详细分析下其中参数的含义,如下所示:

  • -Xmx2048m:指定 JVM 最大允许分配的堆内存为 2048MB,它会采用按需分配的方式。
  • -XX:MaxPermSize=512m:指定 JVM 最大允许分配的非堆内存为 512MB,同上堆内存一样也是按需分配的。

11、配置 DexOptions

我们可以将 dexOptions 配置项中的 maxProcessCount 设定为 8,这样编译时并行的最大进程数数目就可以提升到 8 个。

12、使用 walle 提升打多渠道包的效率

walle 是 Android Signature V2 Scheme 签名下的新一代渠道包打包神器,它在 Apk 中的 APK Signature Block 区块添加了自定义的渠道信息以生成渠道包,因而提高了渠道包的生成效率。此外,它也可以作为单机工具来使用,也可以部署在 HTTP 服务器上来实时处理渠道包 Apk 的升级网络请求,有需要的同学可以参考美团的 walle

13、设置应用支持的语言

如果应用没有做国际化,我们可以让应用仅仅支持 中文的资源配置,即将 resConfigs 设置为 “zh”。如下所示:

android {
defaultConfig {
resConfigs “zh”
}
}

14、使用增量编译

Gradle 的构建方式通常来说细分为以下 三种:

  • 1)、Full Build:全量构建,即从0开始构建。
  • 2)、Incremental build java change:增量构建Java改变,修改源代码后的构建,且之前构建过。
  • 3)、Incremental build resource change:修改资源文件后的构建,且之前构建过。

在 Gradle 4.10 版本之后便默认使用了增量编译,它会测试自上次构建以来是否已更改任何 gradle task 任务输入或输出。如果还没有,Gradle 会将该任务认为是最新的,因此跳过执行其动作。由于 Gradle 可以将项目的依赖关系分析精确到类级别,因此,此时仅会重新编译受影响的类。如果在更老的版本需要启动增量编译,可以使用如下配置:

tasks.withType(JavaCompile) {
options.incremental = true
}

15、使用循环进行依赖优化(✨)

在 Awesome-WanAndroid 项目的 app moudle 的 build.gradle 中,有将近几百行的依赖代码,如下所示:

dependencies {
implementation fileTree(include: [‘*.jar’], dir: ‘libs’)

// 启动器
api files(‘libs/launchstarter-release-1.0.0.aar’)

//base
implementation rootProject.ext.dependencies[“appcompat-v7”]
implementation rootProject.ext.dependencies[“cardview-v7”]
implementation rootProject.ext.dependencies[“design”]
implementation rootProject.ext.dependencies[“constraint-layout”]

annotationProcessor rootProject.ext.dependencies[“glide_compiler”]

//canary
debugImplementation (rootProject.ext.dependencies[“leakcanary-android”]) {
exclude group: ‘com.android.support’
}
releaseImplementation (rootProject.ext.dependencies[“leakcanary-android-no-op”]) {
exclude group: ‘com.android.support’
}
testImplementation (rootProject.ext.dependencies[“leakcanary-android-no-op”]) {
exclude group: ‘com.android.support’
}

有没有一种好的方式不在 build.gradle 中写这么多的依赖配置?

有,就是 使用循环遍历依赖。答案似乎很简单,但是要想处理在依赖时遇到的所有情况,并不简单。下面,我直接给出相应的适配代码,大家可以直接使用。

首先,在 app 下的 build.gradle 的依赖配置如下所示:

// 处理所有的 aar 依赖
apiFileDependencies.each { k, v -> api files(v)}

// 处理所有的 xxximplementation 依赖
implementationDependencies.each { k, v -> implementation v }
debugImplementationDependencies.each { k, v -> debugImplementation v }
releaseImplementationDependencies.each { k, v -> releaseImplementation v }
androidTestImplementationDependencies.each { k, v -> androidTestImplementation v }
testImplementationDependencies.each { k, v -> testImplementation v }
debugApiDependencies.each { k, v -> debugApi v }
releaseApiDependencies.each { k, v -> releaseApi v }
compileOnlyDependencies.each { k, v -> compileOnly v }

// 处理 annotationProcessor 依赖
processors.each { k, v -> annotationProcessor v }

// 处理所有包含 exclude 的依赖
implementationExcludes.each { entry ->
implementation(entry.key) {
entry.value.each { childEntry ->
exclude(group: childEntry)
}
}
}
debugImplementationExcludes.each { entry ->
debugImplementation(entry.key) {
entry.value.each { childEntry ->
exclude(group: childEntry.key, module: childEntry.value)
}
}
}
releaseImplementationExcludes.each { entry ->
releaseImplementation(entry.key) {
entry.value.each { childEntry ->
exclude(group: childEntry.key, module: childEntry.value)
}
}
}
testImplementationExclude.each { entry ->
testImplementation(entry.key) {
entry.value.each { childEntry ->
exclude(group: childEntry.key, module: childEntry.value)
}
}
}
androidTestImplementationExcludes.each { entry ->
androidTestImplementation(entry.key) {
entry.value.each { childEntry ->
exclude(group: childEntry.key, module: childEntry.value)
}
}
}

然后,在 config.gradle 全局依赖管理文件中配置好对应名称的依赖数组即可。代码如下所示:

dependencies = [
// base
“appcompat-v7” : “com.android.support:appcompat-v7:${version[“supportLibraryVersion”]}”,

]

annotationProcessor = [
“glide_compiler” : “com.github.bumptech.glide:compiler:${version[“glideVersion”]}”,

]

apiFileDependencies = [
“launchstarter” :“libs/launchstarter-release-1.0.0.aar”
]

debugImplementationDependencies = [
“MethodTraceMan” : “com.github.zhengcx:MethodTraceMan:1.0.7”
]

implementationExcludes = [
“com.android.support.test.espresso:espresso-idling-resource:3.0.2” : [
‘com.android.support’ : ‘support-annotations’
]
]

三、Gradle 常用命令

1、Gradle 查询命令

1)、查看主要任务

./gradlew tasks

2)、查看所有任务,包括缓存任务等等

./gradlew tasks --all

2、Gradle 执行命令

1)、对某个module [moduleName] 的某个任务[TaskName] 运行

./gradlew :moduleName:taskName

3、Gradle 快速构建命令

Gradle 提供了一系列的快速构建命令来替代 IDE 的可视化构建操作,如我们最常用的 clean、build 等等。需要注意的是,build 命令会把 debug、release 环境的包都构建出来。

1)、查看构建版本

./gradlew -v

2)、清除 build 文件夹

./gradlew clean

3)、检查依赖并编译打包

./gradlew build

4)、编译并安装 debug 包

./gradlew installDebug

5)、编译并打印日志

./gradlew build --info

6)、编译并输出性能报告,性能报告一般在构建工程根目录 build/reports/profile 下

./gradlew build --profile

总结

写到这里也结束了,在文章最后放上一个小小的福利,以下为小编自己在学习过程中整理出的一个关于Flutter的学习思路及方向,从事互联网开发,最主要的是要学好技术,而学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯,更加需要准确的学习方向达到有效的学习效果。
由于内容较多就只放上一个大概的大纲,需要更及详细的学习思维导图的
还有高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术资料,并且还有技术大牛一起讨论交流解决问题。

跨平台开发:Flutter.png

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

的大纲,需要更及详细的学习思维导图的
还有高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术资料,并且还有技术大牛一起讨论交流解决问题。**

[外链图片转存中…(img-tyzqordF-1715760430012)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值