ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Flutter构建卡在Gradle?从卡死35分钟到1分半的优化指南

Flutter构建卡在Gradle?从卡死35分钟到1分半的优化指南 先说个真实场景你新建了一个Flutter项目兴冲冲执行flutter run控制台前几行很正常然后卡在Running Gradle task assembleDebug...这一行Android Studio下面那个进度条像睡着了一样短则三五分钟长则半个多小时。我接触Flutter以来这类问题见得太多了而且新手遇到的第一反应往往是“我代码写错了”或者“Flutter是不是坏了”其实大概率跟你手头的Dart代码没有半毛钱关系问题出在Gradle构建环境和依赖下载上。这篇文章不绕弯子直接把卡住的原理、排障思路、离线包和镜像仓库的配置方式、版本匹配规则全部讲清楚最后再附一个从35分钟压到1分半的完整复盘案例。内容适配Windows、macOS、Linux三平台新手可以照抄老手也能查漏补缺。1. 先分清卡在Gradle构建阶段还是应用启动阶段1.1 同一个界面表现两种完全不同的卡法flutter run执行之后终端输出Running Gradle task assembleDebug...注意这句英文直译过来是“正在运行Gradle的assembleDebug任务”它代表的是构建APK这个阶段跟应用在手机上是否启动是两码事。我把常见的“卡住”分成两类第一类是构建卡住表现是终端一直停留在这行APK没生成Android Studio的Build窗口有进度条但在缓慢走动或者干脆不动。第二类是构建其实已经完成了但应用在设备上白屏很久或者flutter run输出Flutter run key commands之后点不动那属于运行时启动慢、渲染引擎初始化、首帧渲染慢的问题。判断方法很简单在终端里看到Built build/app/outputs/flutter-apk/app-debug.apk字样说明APK已经打出来了再往后卡就是设备侧的问题如果始终没有这个输出那就是Gradle这一层的锅。很多新手把这两类混在一起折腾半天方向就错了。1.2 assembleDebug在Flutter构建链路里的位置理解Gradle在Flutter里的位置才不会乱改配置。一条完整的Android构建链路是这样的Flutter工具链先调用Gradle WrapperGradle Wrapper负责下载并启动指定版本的Gradle然后Gradle读取android/app/build.gradle也可能是.kts里的配置拉取Android Gradle Plugin也就是AGP再由AGP组织编译资源、处理Manifest、打包、签名等一堆工作。换句话说assembleDebug这个任务本身包含很多子任务合并资源、处理Dart代码编译产物、打包JNI库、生成APK等。其中任何一个子任务卡住你看到的都是同一句Running Gradle task assembleDebug...。首次运行时还有一个很关键的因素Gradle本身没有安装需要先下载一个100多MB的压缩包然后所有第三方依赖也要逐个下载。这两步叠加首次构建慢到怀疑人生就非常正常了。如果你的项目是旧版本升级上来的或者团队仓库里带了别人改过的Gradle配置那构建链路里还会混入版本不匹配、依赖冲突等疑难杂症。先把这条链路记住后面的排障才有坐标。2. 动手前先确诊卡住的时候你到底卡在哪一步2.1 三分钟快速定位法用详细日志代替瞎等发现卡住之后不要急于一遍遍重启Android Studio先做三件事。第一把终端里这次运行停掉改用flutter run -v重新跑一次-v是verbose模式会把Gradle、依赖下载、资源处理的详细输出全部打出来。命令大概是flutter run -v -d 设备Id如果只是要验证能否构建也可以执行flutter build apk --debug -v这一步不需要连着手机。第二打开本地Gradle缓存目录看大小变化。Windows下是C:\Users\你的用户名\.gradlemacOS和Linux是~/.gradle。重点关注两个子目录wrapper/dists和caches。如果wrapper/dists里出现一个正在缓慢增大的gradle-8.x-all.zip文件说明卡在Gradle发行包下载如果zip已经下载完但caches目录在不停写入类文件说明在下载Maven依赖。第三打开任务管理器或者系统监控工具观察Gradle进程、Java进程的CPU和内存占用。如果CPU一直有在跑、内存也在涨说明Gradle正在干活只是慢如果进程CPU几乎为0、网络下行速度为0那就是卡在某个等待上通常是网络连接超时。2.2 常见卡点四梯队根据我实际遇到的故障assembleDebug卡住可以归成四个梯队。第一梯队是卡在Downloading https://services.gradle.org/distributions/gradle-8.x-bin.zip这类日志上特征是进度条长时间不变这是Gradle发行包下载慢尤其在国内网络环境下非常明显。第二梯队是Gradle发行包装好了但卡在依赖解析阶段日志里会反复出现Could not resolve、Download等字样这是Maven仓库访问慢涉及的组件包括AGP、Kotlin插件、AndroidX库等一个项目依赖几十上百个jar包任何一次超时都可能整体停滞。第三梯队是SDK相关错误信息里常见SDK location not found或者卡在Installing Android SDK component这是本机Android SDK缺少对应版本Android Studio在后台下载Platform和Build Tools。第四梯队是编译和资源处理阶段日志里能看到Executing task :app:compileDebugKotlin、:app:mergeDexDebug、:app:processDebugResources等这一般不是网络问题而是机器内存不够或插件配置有问题。先判断属于哪个梯队再决定用哪种解法。不要一上来就把整个Gradle删了重装方向错了只会更绝望。3. 对症下药按卡点分类的解决方案3.1 高频卡点速查表我先把最常见的几种现象、根因和对应操作整理成一张速查表你在处理时直接对照卡住/报错现象根因优先处理方式卡在Downloading https://services.gradle.org/distributions/...Gradle发行包下载慢配置国内镜像地址或使用本地离线包日志频繁出现Could not resolveMaven依赖下载失败或超时在仓库配置中加入阿里云镜像并把它放到最前卡在Resolve dependencies of :app:debugCompileClasspathAndroidX/AGP依赖拉取慢配置镜像检查AGP版本是否匹配出现SDK location not found本地Android SDK路径未配置在android/local.properties里手动指定sdk.dir卡在:app:compileDebugKotlinKotlin编译慢或内存不足调整gradle.properties堆内存确认JDK版本匹配同步时一直Gradle Sync失败Gradle版本与AGP版本冲突检查gradle-wrapper.properties与AGP版本匹配表这张表不覆盖所有情况但覆盖了八成以上新手卡住的原因。后面的内容会围绕这几个根因展开。3.2 离线包与镜像仓库的落地配置针对第一梯队和第二梯队核心解法就是把Gradle发行包和Maven依赖的来源换成国内可稳定访问的地址。Gradle发行包这一层有两种做法我推荐首次构建的机器直接上离线解压方式最省事。先看你项目里android/gradle/wrapper/gradle-wrapper.properties这个文件它里面有一行distributionUrlhttps\://services.gradle.org/distributions/gradle-8.x-bin.zip这个地址就是下载Gradle发行包的来源。你到浏览器里访问这个地址把对应版本的zip包下载下来注意要下载bin版本而不是带all的其实两个都能用但bin体积小一些。然后把distributionUrl改成distributionUrlfile\:///D:/gradle/gradle-8.5-bin.zipmacOS或Linux下改成你自己的路径例如distributionUrlfile\:///Users/你的用户名/gradle/gradle-8.5-bin.zip注意Windows下路径前缀是三斜杠这一点很多人写错。如果你不想手动下载也可以用国内镜像地址腾讯云的Gradle镜像相对稳定distributionUrlhttps\://mirrors.cloud.tencent.com/gradle/gradle-8.5-bin.zipmaven依赖这一层要找到android/settings.gradle老版本是android/build.gradle。新版Flutter项目默认生成的是settings.gradle.kts在pluginManagement的repositories和dependencyResolutionManagement的repositories里加镜像。一个完整的例子如下pluginManagement { repositories { maven { url uri(https://maven.aliyun.com/repository/google) } maven { url uri(https://maven.aliyun.com/repository/public) } maven { url uri(https://maven.aliyun.com/repository/gradle-plugin) } google() mavenCentral() gradlePluginPortal() } } dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { maven { url uri(https://maven.aliyun.com/repository/google) } maven { url uri(https://maven.aliyun.com/repository/public) } google() mavenCentral() } }如果项目是老式的build.gradle就在allprojects的repositories里加同样的三个镜像地址。这套配置我实测在多个项目里都稳定阿里云的google仓库镜像基本覆盖了Android依赖。注意镜像地址要写在google()和mavenCentral()前面因为Gradle按顺序查找仓库找到就停止。把镜像放前面能大幅缩短依赖解析时间尤其是网络波动时期放在后面会导致部分依赖仍然去慢速源头拉取。4. 从根上优化一份合理的Gradle配置长什么样4.1 gradle.properties推荐参数很多人只知道换镜像却忽略了本地构建参数导致明明网络没问题构建还是慢吞吞的。Flutter项目里android/gradle.properties这个文件值得好好调。我在这份文件里长期使用下面这套配置org.gradle.jvmargs-Xmx4096m -XX:MaxMetaspaceSize1024m -XX:HeapDumpOnOutOfMemoryError org.gradle.paralleltrue org.gradle.cachingtrue org.gradle.daemontrue org.gradle.configureondemandtrue android.useAndroidXtrue kotlin.incrementaltrue逐行解释一下。org.gradle.jvmargs控制Gradle构建进程的最大堆内存-Xmx4096m代表4GB如果你的开发机内存是16GB往上可以设到6G到8G但如果机器总内存只有8GB设太大反而会因为系统频繁换页变得更慢。-XX:MaxMetaspaceSize1024m控制元空间大小Gradle和Kotlin编译会加载大量类元空间不足会直接报OutOfMemoryError。org.gradle.paralleltrue允许多个子任务并行执行org.gradle.cachingtrue开启构建缓存configureondemand意味着只配置需要的项目对单模块项目影响不大但多模块能省不少时间。android.useAndroidXtrue是AndroidX迁移开关现在新建的项目都是默认true如果你的项目里还有老库没迁移、而且依赖库里确实有非AndroidX的老包那可能需要同时开android.enableJetifiertrue但Jetifier本身很耗时能不开就别开。这套配置改完以后建议重启Android Studio或者执行一次flutter clean再跑否则部分参数可能不会立刻生效。特别是第一次从默认配置改到这些参数构建进程需要重启才能读到新JVM参数。4.2 AGP、Gradle、JDK版本匹配关系版本匹配是Gradle相关故障里最隐蔽的一类坑。Gradle、AGP、JDK三者互相有约束版本不对可能表现为各种奇奇怪怪的错误。比如你看到You are applying Flutters main Gradle plugin imperatively using the apply这类报错往往也是项目模板和Gradle插件应用方式不匹配导致的我后面单独说。先给一个参考对应关系实际以你本机flutter create生成的模板为准Flutter版本范围默认Gradle版本默认AGP版本JDK要求Flutter 3.10 ~ 3.137.6.x8.0.xJDK 17Flutter 3.16 ~ 3.198.1.x ~ 8.3.x8.1.x ~ 8.3.xJDK 17Flutter 3.228.48.3JDK 17Flutter 3.248.58.5JDK 17JDK 17这个点尤其重要。Flutter 3.10以后官方模板默认要求JDK 17如果你只是装了JDK 11构建时可能会报Unsupported class file major version之类的错误。Android Studio 2023以上版本自带的JBR就是JDK 17所以用Android Studio启动通常没问题但用命令行跑flutter run时如果系统环境变量JAVA_HOME指向了旧JDK就会出问题。我的建议是命令行和Android Studio统一使用同一个JDK或者直接在项目android/local.properties里加上org.gradle.java.homeC:/Program Files/Android/Android Studio/jbr这个值是绝对路径Windows下注意反斜杠和空格处理。macOS下通常是/Applications/Android Studio.app/Contents/jbr/Contents/Home。写上以后Gradle会用指定JDK启动构建不会再看系统JAVA_HOME能避免很多环境不一致引发的麻烦。4.3 关于assembleDebug卡死的另一个隐蔽原因SDK组件下载与索引除了Gradle发行包和Maven依赖SDK组件下载也会导致长时间停滞。你第一次新建项目时Gradle会根据compileSdk版本去检查Android SDK里对应的Platform和Build Tools是否齐全。如果缺失Gradle会自动触发下载但下载过程不会在终端里显示太明显的进度看起来就像卡死了。最简单的处理方式是在Android Studio的SDK Manager里提前装好常用的SDK Platform例如Android 13API 33、Android 14API 34、Android 15API 35以及对应的Build Tools和Platform Tools。手动装完Gradle检查时就一路通过不会在构建半路去现下载。还有一个容易被忽略的环节Android Studio的索引。首次打开项目时IDEA会在后台做文件索引和Gradle Sync这个阶段CPU占用极高如果同时跑flutter run两者抢资源会显得构建异常慢。这时候你看终端日志Gradle可能一直在推进只是很慢。解决办法是等Sync完成再跑构建或者临时在Android Studio里关闭自动Sync。5. 实操复盘从卡死35分钟到1分半跑起来5.1 原始环境记录我拿一个真实项目复盘一下处理全过程。机器是Windows 10内存32GBFlutter版本3.19.5新建了一个标准模板项目Android Studio版本为最新稳定版2024.1设备是Android模拟器。第一次执行flutter run终端打印到Running Gradle task assembleDebug...之后就没动静了等了大约10分钟进度条纹丝不动又等了25分钟终于动了一下最终首次构建耗时约35分钟。这种表现几乎可以断定是Gradle发行包和首轮依赖下载叠加导致的因为一个全新项目没有任何本地缓存所有东西都要从零拉取。在C:\Users\用户名\.gradle\wrapper\dists目录下我看到gradle-8.3-all.zip正在下载下载速度只有几十KB每秒按这个速度要下完确实要很久。5.2 分步操作与完整配置整个处理过程分成四步每一步都有明确目的。第一步杀掉当前构建进程打开android/gradle/wrapper/gradle-wrapper.properties记录当前distributionUrl对应的版本我这里是gradle-8.3-all.zip。去浏览器下载同样的zip包到本地目录这里注意要下载和你项目完全相同的版本不能随便拿一个高版本顶替否则会引发AGP不兼容。下载完成后把distributionUrl改成本地文件路径distributionUrlfile\:///D:/gradle/gradle-8.3-all.zip第二步打开android/settings.gradle.kts把阿里云镜像加到pluginManagement和dependencyResolutionManagement里具体代码就是上面第三节那段这里不重复。这里有一个细节新版模板的settings.gradle.kts开头有一段获取Flutter SDK路径的代码镜像配置加在repositories块里即可不要动其他内容。第三步打开android/gradle.properties把第四节那套JVM参数和并行配置写进去。这台机器内存32GB我把-Xmx设成了6144m给Kotlin编译和Dex打包留足空间。第四步回到项目根目录执行三连flutter clean、flutter pub get、flutter run -v。第一次依然会下载依赖但因为Gradle发行包已经走本地文件下载大头已经被去掉剩余Maven依赖走阿里云镜像速度明显比之前快。实测第二次构建从执行到出Built build/app/outputs/flutter-apk/app-debug.apk只用了1分32秒。5.3 为什么这套操作有效表面上看我只是改了三个文件但每一步都在解决特定瓶颈。distributionUrl指向本地文件后Gradle不再访问境外下载服务器省掉了一个100多MB文件的长途传输。阿里云镜像解决了接下来几十上百个jar包的拉取问题这些jar包总大小可能超过300MB而dl.google.com在多数网络环境下远不如阿里云。JVM参数解决的是机器能力没有被充分利用的问题默认的-Xmx偏小Kotlin编译和Gradle并行任务一起挤在2GB堆内存里动不动就触发GC停顿。这里我补充一个对比表格直观展示效果阶段优化前优化后Gradle发行包下载境外地址几十KB每秒本地文件秒装Maven依赖下载默认仓库部分超时阿里云镜像稳定快速Gradle堆内存默认值偏小频繁GC6GB编译顺畅并行构建未开启开启多任务并行首次构建总耗时约35分钟约7分钟二次构建总耗时约4分钟约1.5分钟依赖下载完毕后后续构建即使不改配置也会变快因为本地缓存已经生效。但正确的配置能保证你在新机器、新项目上不再踩同样的坑。6. 常见问题与排查技巧实录6.1 高频问题速查表除了上面讲的卡住我整理了几个我在评论区、社群里高频见到的相关问题和处理方法。问题1flutter run一直卡在0%终端没有任何输出。这种情况多半是Flutter工具本身在初始化插件或者等待设备先按q退出执行flutter doctor -v检查是不是设备连接或者license没接受再重新跑。问题2构建时提示Could not find com.android.tools.build:gradle:8.x.x。这是AGP依赖找不到去settings.gradle.kts里确认阿里云镜像里的google仓库是否配置正确。如果项目里同时存在多个仓库管理配置找到真正生效的那一份。问题3报错Failed to install the following Android SDK packages。这是本地SDK缺组件用Android Studio的SDK Manager勾选对应版本的Android SDK Platform和SDK Build-Tools接受License后重新同步。问题4卡在Running Gradle task assembleDebug...永远不动但日志没有任何报错。查看~/.gradle缓存目录大小如果一直不增长基本是网络连接在等待超时。把镜像配好、Gradle离线包放好再重启一次。如果磁盘空间被占满或杀毒软件在扫描构建目录也可能出现假死Windows用户可以把.gradle和build目录加入杀毒软件的排除列表。问题5Gradle Sync失败提示Unsupported Java. Your build is currently configured to use Java XX.这是JDK版本和Gradle不匹配去android/local.properties里指定JDK 17路径或者升级Android Studio自带JBR后重启。问题6构建成功但App启动白屏很久。这个跟本文主题的Gradle阶段不一样属于运行时渲染方面的问题。Flutter 3.10以后的Android默认启用Impeller渲染引擎部分设备首帧shader编译会导致启动变慢可以在AndroidManifest.xml的application节点加一段临时关闭Impellermeta-data android:nameio.flutter.embedding.android.EnableImpeller android:valuefalse /注意这只是临时回退到Skia排查问题不能作为长期方案等Flutter版本升级后再验证。6.2 资深经验配置过程中容易踩的坑我最后说几个平时写配置最容易踩的细节。第一不要只改根目录的配置而忽略android子目录。Flutter项目的Gradle配置全部位于android目录下你在项目根目录找不到build.gradle不要奇怪。有些教程讲的settings.gradle路径和Flutter模板不一致一定要先看自己项目的目录结构。第二镜像仓库的顺序会影响成败。把阿里云镜像放在最前面是正确做法但也不能完全删掉google()和mavenCentral()因为有些特别冷门的依赖只在原始仓库有保留它们作为兜底才稳妥。第三改完gradle-wrapper.properties之后不要忘了Gradle Wrapper会校验distributionSha256Sum。如果你项目里配置了这个哈希值改用镜像地址或本地文件后哈希校验大概率会失败因为镜像文件哈希不一定一致。遇到这种情况把那一行注释掉或者改成对应文件的实际SHA256。第四多个Flutter项目在同一个机器上构建时Gradle版本最好保持一致。Gradle的本地缓存是按版本分目录的如果你今天跑一个8.3的项目、明天跑一个8.1的项目两套Gradle发行包和依赖缓存都要分别准备占用磁盘翻倍首次构建也要各来一遍。第五遇到无法解释的Gradle卡死别急着重装Android Studio。先执行./gradlew --stop停掉所有Gradle守护进程再执行flutter clean把android/.gradle目录删掉重新同步很多诡异问题就这样解决了。这个套路我至少用过几十次成功率在八成以上。我个人在实际操作中的体会是Gradle的卡死问题九成以上是网络和缓存问题真正代码层面的构建死锁极少见。只要你愿意花五分钟看清日志、判断卡点再按镜像加离线包的方案处理绝大多数项目都能跑起来。最后再分享一个小技巧当你配置好一套稳定的Gradle环境后把gradle-wrapper.jar、gradle-wrapper.properties、settings.gradle.kts、gradle.properties这几个文件复制一份留作模板之后新建项目直接替换过去能省掉很多重复排障的时间。
返回列表