Android Studio Ladybug(2024.2.2) 导入和构建项目耗时过长
结论
增加 Android Studio 堆内存,或者启用 org.gradle.parallel、org.gradle.daemon,通常不能直接解决导入缓慢的问题。首先要确认时间花在哪个阶段:
- Gradle Sync 与依赖解析;
- Gradle 配置阶段;
- Kotlin/KAPT、资源处理、Dex 或原生构建;
- Android Studio 索引;
- 网络、磁盘或杀毒软件扫描。
根据现有配置,建议先检查动态版本依赖、JitPack 等远程仓库、第三方 Gradle 插件、KAPT,以及首次下载的大型 SDK。尤其要注意这项依赖:
implementation 'com.facebook.android:facebook-android-sdk:[8,9)'
它使用了动态版本范围。Gradle 为了确定实际版本,可能反复访问仓库并检查元数据。多个 com.github.* 依赖通常还会查询 JitPack,网络不稳定时,Gradle Sync 会明显变慢。hypersdk.plugin、Firebase Crashlytics、Google Services 等插件也会增加配置时间,因此不能只看依赖数量来判断瓶颈。
先确定到底慢在哪里
不要反复执行 Clean Build。它会清除增量构建成果,让测量结果失真。先在项目根目录分别执行:
./gradlew help --profile
./gradlew assembleStagingDebug --profile
Windows 使用:
gradlew.bat help --profile
gradlew.bat assembleStagingDebug --profile
help 基本不执行编译任务,主要反映 Gradle 的启动和项目配置成本。assembleStagingDebug 可以显示实际构建任务花了多长时间。报告通常生成在:
build/reports/profile/
可以按下面的情况判断:
- 如果
help已经很慢,重点检查插件、构建脚本、依赖仓库和配置阶段。 - 如果
help很快,但assembleStagingDebug很慢,查看报告中的慢任务。 - 如果命令行构建很快,但 Android Studio 导入后长时间没有响应,问题更可能出在 IDE 索引、文件扫描或插件上。
- 如果首次构建很慢,第二次明显加快,通常是因为首次需要下载依赖、解压 SDK、生成缓存或建立索引,未必属于异常。
还可以使用 Gradle Build Scan 查看更完整的时间线:
./gradlew assembleStagingDebug --scan
Build Scan 可能会把构建信息上传到外部服务。企业项目使用前,应先确认代码和数据安全策略。不能上传时,使用本地 --profile 即可。
在 Android Studio 中,还可以打开 Build Analyzer,查看 Kotlin、资源处理、Dex、注解处理器等任务的耗时,以及增量构建是否生效。
排查依赖解析和网络问题
先用下面的命令观察依赖解析是否长时间停顿:
./gradlew assembleStagingDebug --info
--debug 会生成大量日志,一般只在 --info 无法定位问题时使用。不要公开包含凭据、私有仓库地址或本机路径的完整日志。
固定动态依赖版本
将:
implementation 'com.facebook.android:facebook-android-sdk:[8,9)'
替换成项目已经验证过的明确版本,例如:
implementation 'com.facebook.android:facebook-android-sdk:<verified-version>'
不能脱离项目兼容性直接指定具体版本。先通过依赖报告确认当前解析结果:
./gradlew app:dependencies --configuration stagingDebugRuntimeClasspath
也可以用下面的命令确认某个库为什么会被引入:
./gradlew app:dependencyInsight \
--dependency facebook-android-sdk \
--configuration stagingDebugRuntimeClasspath
动态版本、latest.release 和 SNAPSHOT 依赖都会增加远程元数据检查,还可能让不同时间的构建得到不同的依赖树,建议全部固定版本。
检查仓库声明
仓库越多,当某个依赖不存在或网络请求超时时,Gradle 越可能依次查询多个地址。建议在 settings.gradle 中集中声明仓库,只保留项目确实需要的地址:
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
// 仅在确实使用 com.github.* 的 JitPack 依赖时保留
maven {
url = uri("https://jitpack.io")
content {
includeGroupByRegex("com\\.github\\..*")
}
}
}
}
如果某个私有仓库或 JitPack 无法访问,增加 IDE 内存也不会改善同步速度。可以暂时通过浏览器或命令行验证仓库连通性,但不要把 --refresh-dependencies 作为日常构建参数,因为它会强制重新检查依赖。
如果所有依赖都已经缓存,可以暂时执行:
./gradlew assembleStagingDebug --offline
离线构建很快、在线构建很慢时,问题基本可以缩小到仓库访问、代理、DNS、证书或动态版本解析。缺少依赖的首次导入不适合使用离线模式。
逐个隔离第三方 Gradle 插件
Gradle 插件会在配置或构建过程中运行,对速度的影响往往比普通 implementation 依赖更直接。建议在独立分支中逐个暂时禁用插件,然后比较 ./gradlew help --profile 的结果:
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
// 仅用于诊断,逐个禁用后重新测量
// id 'com.google.gms.google-services'
// id 'com.google.firebase.crashlytics'
// id 'hypersdk.plugin'
}
禁用插件后,项目可能因为缺少生成文件或扩展配置而无法完成构建。不过,help 和 Gradle Sync 的耗时变化仍然可以帮助判断配置阶段的瓶颈。不要一次删除所有插件,否则无法确认具体是哪一个插件造成了问题。
同时检查根项目中的以下内容:
buildscript和插件版本;settings.gradle;- 自定义 Gradle 脚本;
buildSrc或 convention plugin;- 插件配置是否会执行网络请求、Git 命令或遍历大量文件。
优化 Gradle 配置
可以在项目的 gradle.properties 中使用相对保守的配置:
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.jvmargs=-Xmx4g -Dfile.encoding=UTF-8
kotlin.incremental=true
需要注意:
- Gradle Daemon 在常规环境中通常已经默认启用,显式声明后不一定有变化。
org.gradle.parallel=true主要适用于包含多个可并行模块的项目,单模块应用的收益可能很小。org.gradle.caching=true只有在任务支持缓存且输入没有变化时才有效。-Xmx并不是越大越好。物理内存不足时,过大的堆会导致系统换页,速度反而更慢。- Android Studio 的 IDE Heap 和 Gradle JVM Heap 是两个不同的设置。修改 IDE 堆并不会改变 Gradle Daemon 的内存。
确认插件兼容后,可以测试配置缓存:
org.gradle.configuration-cache=true
org.gradle.configuration-cache.problems=warn
然后执行两次:
./gradlew help
./gradlew help
配置缓存的效果要到第二次运行才会体现。如果出现插件不兼容、任务读取未声明状态或构建结果异常,应先关闭配置缓存并解决兼容问题,不要长期用 problems=warn 掩盖错误。
检查 KAPT 和 Kotlin 编译
项目应用了:
id 'kotlin-kapt'
但现有依赖中没有明显的 kapt 声明。如果整个项目确实没有使用注解处理器,可以在验证后移除该插件:
plugins {
id 'com.android.application'
id 'kotlin-android'
// id 'kotlin-kapt'
}
先搜索所有模块中是否存在:
kapt 'group:artifact:version'
还要确认是否有其他依赖插件自动配置了 KAPT。未经检查直接删除,可能导致生成代码缺失。
如果项目使用了注解处理器,可以通过 Build Analyzer 或 Gradle Profile 检查相关任务,例如:
kaptGenerateStubs...
kapt...
compile...Kotlin
如果某个处理器不支持增量处理,即使只修改了少量代码,也可能触发大范围重新生成。某些库同时支持 KSP,可以评估迁移,但必须先确认所用版本和生成代码行为是否兼容。
修正并简化 Android DSL
compileSdk 应放在 android 顶层,而不是 defaultConfig 中。建议整理成下面的结构:
android {
compileSdk 34
ndkVersion "23.2.8568313"
defaultConfig {
minSdk 24
targetSdk 34
versionCode 118
versionName "12.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
signingConfig signingConfigs.debug
}
flavorDimensions "api"
productFlavors {
staging {
dimension "api"
buildConfigField "String", "API_BASE_URL", API_BASE_URL
buildConfigField "String", "API_CHECKSUM_URL", CHECKSUM_URL
}
production {
dimension "api"
buildConfigField "String", "API_BASE_URL", API_BASE_URL
buildConfigField "String", "API_CHECKSUM_URL", CHECKSUM_URL
}
}
buildFeatures {
viewBinding true
}
}
这项调整主要是为了保证 DSL 正确,减少兼容性方面的歧义,本身不一定能明显改善性能。
项目还声明了:
externalNativeBuild {
cmake {
version "3.10.2"
}
}
如果项目没有 C/C++ 代码,也没有配置 CMakeLists.txt,需要确认是否还需要 CMake、NDK 和相关插件配置。如果确实使用了原生代码,应查看 .cxx 目录中的配置和构建日志。ABI 数量、CMake 配置和大型原生依赖都可能增加导入及构建时间。不要只为了提速就删除原生配置,否则可能影响第三方 SDK 或打包结果。
减少变体和不必要任务
两个 product flavor 与多个 build type 会组合出多个变体。Android Studio 同步时需要建立变体模型,项目越大,这部分的耗时越明显。可以只启用日常开发需要的变体:
android {
variantFilter { variant ->
def names = variant.flavors*.name
if (names.contains("production") && variant.buildType.name == "debug") {
setIgnore(true)
}
}
}
是否使用 variantFilter 以及具体采用哪种 API,取决于项目当前的 Android Gradle Plugin 版本。较新的 AGP 更推荐通过 Android Components API 控制变体。实施前先确认项目使用的 AGP 版本,不要只根据 Android Studio 版本判断。
如果只有 Android Studio 导入慢
如果命令行构建速度正常,但 IDE 一直显示 Indexing、Scanning files 或 Downloading sources,可以重点检查:
- 项目是否放在机械硬盘、网络盘、同步盘或加密目录中;
- 项目目录和 Gradle 缓存是否被杀毒软件实时扫描;
- 大型生成目录、日志、解压文件或 Node.js 目录是否被放进项目;
- 第三方 Android Studio 插件是否在索引期间大量占用 CPU;
- Android Studio 与 Gradle 使用的 JDK 是否兼容;
- 系统是否因为内存不足而频繁换页。
除非组织安全策略允许,否则不要排除项目源码目录或整个 Gradle 缓存的安全扫描。也不要把真正的源码、资源或构建脚本标记为 Excluded。
可以用安全模式,或者暂时禁用非必要的 IDE 插件进行对照。如果只有当前项目很慢,应优先检查项目结构。如果所有项目都慢,再检查 IDE、JDK、磁盘和系统环境。
推荐的排查顺序
- 连续执行两次
./gradlew help --profile,区分首次启动和稳定状态。 - 连续执行两次目标变体构建,不要执行 Clean,比较增量构建表现。
- 用
--offline对照在线构建,判断问题是否来自依赖仓库或网络。 - 固定
facebook-android-sdk:[8,9)等所有动态版本。 - 收紧仓库声明,检查 JitPack、私有仓库和代理的响应速度。
- 在独立分支中逐个禁用
hypersdk.plugin、Crashlytics、Google Services 等插件。 - 通过 Build Analyzer 找出最慢的任务,重点检查 KAPT、Kotlin、资源、Dex 和 CMake。
- 最后再调整 Gradle 堆、并行执行、构建缓存和配置缓存。
拿到 Profile 或 Build Analyzer 中的具体耗时后,才能判断应该优化依赖下载、插件配置、注解处理、原生构建还是 IDE 索引。就当前配置而言,最该先处理的是动态依赖版本、远程仓库访问和第三方插件,而不是继续增加内存。
备注:内容仅供参考。
