记录一次 Flutter 升级遇到的问题

一、问题现象

最近将 Flutter SDK 从 3.29.x 升级到 3.38.10 版本

升级后发现:

📦 APK 打包体积变大了约 1.5 倍

随后定位到问题原因如下。


二、前提说明

升级前后以下配置均未发生变化:

  • Gradle 版本:8.14.2
  • AGP 版本:8.11.0(配置于 settings.gradle.kts
  • Flutter Gradle Plugin 版本:1.0.0(配置于 settings.gradle.kts
  • 打包命令:flutter build apk
  • build.gradle.kts 相关配置未变

原始 build.gradle.kts 配置

kotlin 复制代码
// 原 build.gradle.kts 部分配置如下

buildTypes {
  getByName("release") {
    ndk {
      abiFilters.addAll(listOf("arm64-v8a"))
    }
  }
}

原先通过修改 Gradle 配置,仅保留 arm64-v8a ABI,因此:

flutter build apk 只会生成 arm64-v8a 的 APK


升级后的异常现象

升级到 3.38.10 后,在其他配置未变的情况下:

  • x86_64
  • armeabi-v7a

也被打包进 APK。

随后开始排查原因。


修复方式

修改 build.gradle.kts

kotlin 复制代码
// 新 build.gradle.kts 部分配置如下

buildTypes {
  getByName("release") {
    ndk {
      abiFilters.clear()
      abiFilters.addAll(listOf("arm64-v8a"))
    }
  }
}

重新打包后恢复正常,仅包含 arm64-v8a


三、问题原因分析

通过 GPT 了解到:

Flutter 3.35+ 之后,Flutter SDK 内部的 Flutter Gradle Plugin 实现发生变化,默认构建所有支持的 ABI。

3.35 相关PR GitHub链接


官方默认 ABI

FlutterPluginConstants.kt 中可以看到:

kotlin 复制代码
@JvmStatic val DEFAULT_PLATFORMS =
  listOf(
    PLATFORM_ARM32,
    PLATFORM_ARM64,
    PLATFORM_X86_64
  )

对应架构映射:

kotlin 复制代码
@JvmStatic val PLATFORM_ARCH_MAP =
  mapOf(
    PLATFORM_ARM32 to "armeabi-v7a",
    PLATFORM_ARM64 to "arm64-v8a",
    PLATFORM_X86_64 to "x86_64"
  )

也就是说默认会构建:

  • armeabi-v7a
  • arm64-v8a
  • x86_64

四、插件内部逻辑

核心代码位于:

css 复制代码
<flutter sdk>\packages\flutter_tools\gradle\src\main\kotlin

FlutterPlugin.kt 关键代码

kotlin 复制代码
FlutterPluginUtils.getAndroidExtension(project).buildTypes.forEach { buildType ->
  buildType.ndk.abiFilters.clear()
  FlutterPluginConstants.DEFAULT_PLATFORMS.forEach { platform ->
    val abiValue: String =
      FlutterPluginConstants.PLATFORM_ARCH_MAP[platform]
          ?: throw GradleException("Invalid platform: $platform")
    buildType.ndk.abiFilters.add(abiValue)
  }
}

关键点:

插件会对 abiFilters 先执行 clear(),然后写入默认 ABI。


五、关于官方注释的理解

源码中有一句:

If the user has specified abiFilters in their build.gradle file, those settings will take precedence over these defaults.

翻译:

如果用户在 build.gradle 中指定了 abiFilters,则用户配置优先。

但从实际构建结果来看,并未覆盖默认值。


实际原因:Gradle 生命周期 + 执行顺序

执行顺序如下:

  1. Flutter 插件执行

    • abiFilters.clear()
    • 写入默认 ABI
  2. 然后执行 build.gradle.kts 中的:

kotlin 复制代码
abiFilters.addAll(listOf("arm64-v8a"))

由于只是 addAll(),而不是 clear() 再添加,因此:

最终结果 = 默认 ABI + 配置的 ABI


更准确的理解

这句官方注释的真实含义应该是:

如果用户的配置能够在插件逻辑之后覆盖默认值(例如先 clear()addAll()),那么用户配置才会真正生效。


六、关于 Flutter Gradle Plugin 版本的疑问

虽然在 settings.gradle.kts 中声明:

复制代码
Flutter Gradle Plugin 1.0.0

但:

这个版本号并不代表实际插件实现版本。

真正的实现逻辑:

  • 位于 Flutter SDK 内部
  • 随 Flutter SDK 升级而变化

七、为什么 Flutter 做这个调整?

可能原因包括:

  1. Play Store 强制 64 位支持
  2. 模拟器大量使用 x86_64
  3. CI 构建一致性
  4. 与 App Bundle 行为统一

八、后续方案选择

方式一:通过 abiFilters 控制

缺点:

  • Flutter 插件未来可能继续调整
  • Gradle 层和 Flutter 层逻辑可能冲突

方式二:推荐方式

bash 复制代码
flutter build apk --split-per-abi

优点:

  • 官方推荐方式
  • 构建逻辑清晰
  • 不依赖 Gradle hack

缺点:

  • 会生成多个 APK
  • 构建时间增加

方式三:更适合我的方案

由于目标平台非常明确,仅支持 arm64-v8a

bash 复制代码
flutter build apk --target-platform android-arm64

优点:

  • 只构建指定 ABI
  • 构建时间最短
  • 不依赖 Gradle 层配置
  • 不受 Flutter 插件实现影响

总结

本次问题本质是:

Flutter 3.35+ 修改了内部 Gradle 插件逻辑,默认构建所有 ABI,并在插件执行阶段重写 abiFilters

关键认知:

  • settings.gradle.kts 中声明的插件版本 ≠ 实际实现版本
  • addAll() 不会覆盖默认 ABI
  • 必须 clear() 后再添加
  • 更推荐使用 --target-platform--split-per-abi
相关推荐
SoaringHeart1 天前
Flutter进阶:OverlayEntry 插入图层管理器 NOverlayZIndexManager
前端·flutter
程序员老刘1 天前
Flutter 3.44 有哪些变化?(官方blog完整翻译)
flutter·ai编程·客户端
山屿落星辰1 天前
Flutter 企业级架构设计实战:Clean Architecture + 分层模块化 + 依赖注入全解析
flutter
山屿落星辰1 天前
Flutter 高级特性实战:动画、自定义绘制、平台通道与 Web 优化
前端·flutter
程序软件分享1 天前
2026旗舰版 Java+Flutter 期货微交易系统源码全开源多语言平台
flutter·交易所源码·微盘源码·微交易源码
飞龙14775657467501 天前
Flutter 安全存储插件全面解析:从入门到进阶
flutter
带带弟弟学爬虫__1 天前
dyAPP数据采集-个人主页、发布、搜索、评论
服务器·python·算法·flutter·java-ee·django
icc_tips1 天前
Flutter runAppAsync() 详解:干净的异步应用启动
前端·flutter
恋猫de小郭1 天前
Android 发布全新性能分析器,实用性和性能大升级
android·前端·flutter
恋猫de小郭1 天前
Flutter 3.44 发布啦,超级大版本更新!!!
android·flutter·ios