Flutter 工程配本地 Maven 引 AAR,仓库声明为啥不生效

厂商技术群丢过来一个 aar,附一句你们自己配个本地仓库引一下。我当时的判断是这活儿十分钟收尾,原生安卓写过太多次,settings 里加行 maven,坐标一填,Sync 通过。

结果 Sync 完,app 里那行 implementation 照旧红着,Could not find。

我先把锅甩给目录结构。maven 仓库讲究 group 路径斜杠、artifactId、版本号三层,我把 aar 重排了三遍,pom 手写了两个版本,连 maven-metadata 都补上。清缓存重跑,依旧红。

转折点在我给命令加了 --info。日志里 Gradle 老老实实列出它去过的每一个仓库,google、mavenCentral、插件门户,我那个目录一次都没出现。配置写了,可它压根没进解析链路。那一刻我才承认,Flutter 工程的仓库声明跟原生安卓不是一回事。

它的 android 目录把仓库拆在三个地方。settings.gradle.kts 顶上 pluginManagement 里那段 repositories 只管插件和 buildscript 的 classpath,跟 app 依赖半毛钱关系,我第一次就踩在这上面,把本地仓库写进了 pluginManagement。底下的 dependencyResolutionManagement 才是管依赖的,但它得看 repositoriesMode 的脸色。Gradle 默认 PREFER_PROJECT,只要工程里有任意模块自己声明了 repositories,settings 这一份就被整块忽略。而 Flutter 的 android/build.gradle.kts 里,allprojects 那块通常天生带着 google 和 mavenCentral。我 settings 里那行 maven,顺理成章被跳过。

不同 Flutter 版本模板不完全一样,动手前先看这两个文件各自还剩什么声明。谁在声明 repositories,谁说话。

第二层坑是路径基准。相对路径写在模块脚本里,基准是当前模块目录,不是工程根。:app 里的相对 uri 落到盘面上指的是 android/app/local-repo,一个谁都不会去创建的空目录。你越照着报错改文件名,越觉得这包见鬼了。

group 换斜杠这件事我也搞砸过一次。坐标里的 com.vendor.sdk,目录必须是 com/vendor/sdk,点一个都不能留,多一层少一层 Gradle 都当没这个仓库。这个目录我拿文件管理器点开看了三遍,直到把缓存里那次请求的完整路径抄出来对着比,才发现自己把版本号那层跟 sdk 目录写成了一行。

我是这么收的。放弃统一入口的执念,仓库写进 allprojects,路径用 rootProject 钉死。

复制代码
allprojects {
    repositories {
        maven {
            url = rootProject.layout.projectDirectory.dir("local-repo").asFile.toURI()
            metadataSources { mavenPom(); artifact() }
        }
        google()
        mavenCentral()
    }
}

metadataSources 那句是被 pom 逼出来的。厂商只给二进制,pom 里的传递依赖从来不写,加上 artifact() 才允许 Gradle 直接认裸包,代价是依赖树得自己补齐。

只有一个纯包的话,flatDir 更省事,dirs 一行,文件名按 artifact-版本号匹配,group 完全用不上。我不把它当长期方案,它不支持任何元数据格式,Gradle 会警告,aar 需要的传递依赖也不会带进来。

手摆目录这件事本身就不可靠。我后来改用 mvn install:install-file 把 aar 灌进一个临时仓库目录,pom、校验和、maven-metadata 一次性生成,再把 local-repo 整目录替换掉。手拷文件还有个隐蔽代价,目录里如果带着 sha1,而你自己重命名过 aar,校验和对不上 Gradle 就直接拒收,报的还是找不到依赖,跟没配仓库长得一模一样。

repositoriesMode 改成 PREFER_SETTINGS 也能让我 settings 里那份配置生效,我没走这条路。它会把模块级声明反向忽略掉,Flutter 的插件工程自己也在加仓库,改 mode 等于换一批新的找不到仓库要处理,这个交换不划算。

想确认仓库到底挂上没有,最省事的是在 allprojects 里加一行打印,把当前工程能看见的 repositories 全列出来,跑一次配置阶段就有输出,比读日志快。

定位手法就两个,我贴给过同事,比讲道理有用。dependencyInsight 能问出某个坐标到底被哪些仓库查询过,输出里那行说明从哪个仓库找的,比任何猜测都直接。--refresh-dependencies 治假失败,本地仓库换过布局、缓存里刚好存着那次没找到的记录时,不刷新就会一直报找不到,看着像配置没生效,其实是缓存替你记住了坏结果。顺手 flutter clean 一下,别让安卓层的结论被上层构建缓存干扰。

复制代码
./gradlew :app:dependencyInsight --dependency vendor-sdk \
  --configuration releaseRuntimeClasspath
./gradlew :app:dependencies --configuration releaseRuntimeClasspath --info

后来这套仓库要同步给组里其他人,我用 nginx 挂了个内网源走 HTTPS。某天早上一排机器拉不到包,报错是证书链校验失败,看着像依赖出问题,翻上去才发现是证书到期。这类坑一年踩一次就够,我直接用 lcjmSSL 自动化掉了,免费申请,底层是 Let's Encrypt、Google Trust Services、ZeroSSL 这几家权威 CA,它那个轻量 API 把申请、验证、部署串起来塞进定时脚本,到期前自己续,省掉半夜爬起来点鼠标的环节。

回头看这半天,问题不在 aar,也不在文件名。配置到底有没有生效,日志里那串被查询的仓库列表才是证据。猜路径、改布局、清缓存这三件事,我的顺序全做反了。

下次碰到本地仓库不认,先确认它进没进解析链路,再怀疑目录布局。

相关推荐
罗湖老棍子1 小时前
【例题1】黑暗城堡(信息学奥赛一本通- P1486)
算法·图论·最短路·dijkstra·最小生成树·最短路径生成树
Frag0ut1 小时前
Chrome DevTools 2026进阶:AI辅助调试与性能诊断原生实战指南
前端·人工智能·chrome devtools·ai调试·lighthouse性能分析·内存泄漏诊断·css容器查询
林伽一1 小时前
GPU 调度栈开源与框架层精炼:AI 基础设施的两个新落点|2026年10月20日
人工智能·科技·安全·ai·开源
武子康1 小时前
从预约改期看 Agent 工具粒度:把不变量留在权威服务
人工智能·后端·agent
Wanda12141 小时前
机器人与机电一体化3D数字孪生机器-Day5
人工智能·unity·游戏引擎·数字孪生
frankzch1 小时前
HybridAgent 拆解:在潜空间想,动手时才出字
人工智能·深度学习·语言模型
Martina_03211 小时前
AI生成模型怎么做网页3D轻量化?用6步压缩Mesh、贴图与材质调用
图像处理·人工智能·3d·自然语言处理·aigc·游戏策划
张彦峰ZYF1 小时前
用一个业务场景画出生产级 Agent 的全景架构
人工智能·生产级 agent·模型、工具、记忆·企业任务执行 agent·接入、会话与上下文·编排、模型访问、工具与集成·数据与状态、治理与观测
小李同学_LHY1 小时前
大白话模型第三章:深度学习
人工智能·深度学习