面试题答案
一键面试优化模块间依赖解析顺序
- 显式依赖声明:
在
build.gradle.kts
文件中,明确声明模块间的依赖关系,避免隐式依赖带来的解析混乱。例如,在一个app
模块依赖common
库模块时,在app
的build.gradle.kts
中:
dependencies {
implementation(project(":common"))
}
- 配置依赖解析策略:
可以在根项目的
build.gradle.kts
中配置依赖解析策略,如优先使用本地缓存,减少远程仓库的请求次数。
allprojects {
repositories {
mavenLocal()
mavenCentral()
}
}
- 使用
dependencySubstitution
: 如果项目中有一些常用依赖可以替换为本地模块或其他更高效的源,可以使用dependencySubstitution
。例如,将一个远程库替换为本地模块:
dependencySubstitution {
substitute(module("com.example:library"))
.using(project(":local-library"))
}
利用 Kotlin DSL 对不同类型模块进行针对性构建优化
- 库模块:
- 配置
kotlinOptions
: 对于库模块,可以优化 Kotlin 编译选项,如设置jvmTarget
等。在库模块的build.gradle.kts
中:
- 配置
kotlin {
jvmToolchain(11)
sourceSets {
val main by getting
main {
kotlin.srcDirs("src/main/kotlin")
resources.srcDirs("src/main/resources")
}
}
}
- **启用 `kotlinx.serialization` 优化**:
如果库模块使用 kotlinx.serialization
,可以优化其配置。例如:
plugins {
kotlin("plugin.serialization") version "1.6.21"
}
kotlin {
sourceSets {
val main by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.3")
}
}
}
}
- 应用模块:
- 配置
applicationVariants
: 应用模块可以针对不同的构建变体进行优化。例如,在build.gradle.kts
中:
- 配置
android {
applicationVariants.all {
// 优化特定变体的构建,如 release 变体
if (name == "release") {
buildConfigField("String", "API_KEY", "\"your_release_api_key\"")
}
}
}
- **优化资源打包**:
可以通过 aaptOptions
优化资源打包。例如:
android {
aaptOptions {
cruncherEnabled = false
useNewCruncher = false
}
}
在构建过程中精准定位性能瓶颈并解决
- 使用 Gradle 构建扫描:
在构建命令中添加
--scan
选项,如./gradlew build --scan
,然后在生成的扫描报告中查看每个任务的执行时间、依赖关系等详细信息,从而定位性能瓶颈任务。 - 使用
gradle.buildScan
插件: 在根项目的build.gradle.kts
中应用插件:
plugins {
id("com.gradle.build-scan") version "1.25.1"
}
buildScan {
termsOfServiceUrl = "https://gradle.com/terms-of-service"
termsOfServiceAgree = "yes"
}
- 分析依赖树:
使用
./gradlew app:dependencies
(假设app
是应用模块名称)命令查看项目的依赖树,检查是否存在重复或不必要的依赖,去除这些依赖以减少构建时间。 - 缓存任务输出:
Gradle 会自动缓存任务输出,但可以进一步优化。例如,对于自定义任务,可以在任务中设置
outputs
属性,明确指定任务输出,以便 Gradle 更好地判断任务是否需要重新执行。
tasks.register("customTask") {
outputs.file("path/to/output/file")
doLast {
// 任务逻辑
}
}