升级Flutter 3.44,我踩了HCPP和AGP 9的坑

Flutter 3.44跟着Google I/O 2026一起发了,我周末升级了一下项目,踩了不少坑,写出来给准备升级的同学参考。

1. 为什么我要升

我项目里嵌了不少原生Android视图------地图、WebView、支付SDK什么的。之前用的是Flutter默认的Platform Views渲染,体验一直不好:滑动时偶尔画面撕裂,触摸响应有延迟,某些设备上WebView内容还会闪烁。

我在issue里蹲了大半年,终于看到3.44出了Hybrid Composition++ (简称HCPP),据说彻底解决了这些问题。再加上Dart 3.12的私有命名参数我也馋了很久,就动手了。

2. 升级过程

项目原本是Flutter 3.29,跨了好几个大版本。

bash 复制代码
flutter upgrade
# 等了挺久,下载完了
flutter --version
# Flutter 3.44.0 • Dart 3.12.0

然后改pubspec.yaml

vbnet 复制代码
environment:
  sdk: '>=3.12.0 <4.0.0'
  flutter: '>=3.44.0'

flutter pub get的时候报错了------fl_chart版本太低不兼容。去pub.dev一看,0.70.0已经适配了,改一下就行:

yaml 复制代码
dependencies:
  fl_chart: ^0.70.0  # 之前是 ^0.68.0

这步倒没踩什么坑。

3. AGP 9.0:第一个大坑

升级完跑了一下Android,直接编译报错。错误信息大概是:

arduino 复制代码
Execution failed for task ':app:compileDebugKotlin'.
> Duplicate kotlin plugin applied

查了一下才知道,Flutter 3.44用了AGP 9.0,而AGP 9.0内置了Kotlin支持 。我项目之前在android/build.gradle里手动加了Kotlin Gradle Plugin,现在冲突了。

解决方案很简单------删掉手动添加的KGP:

arduino 复制代码
// android/build.gradle
// 删掉下面这行
// classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

同时android/app/build.gradle里的:

arduino 复制代码
// 也删掉
// apply plugin: 'kotlin-android'

但如果你维护的是插件而不是应用,还有个额外步骤------必须在pubspec.yaml里把Flutter最低版本约束设成3.44,不然用你插件的开发者升级后会构建失败:

makefile 复制代码
environment:
  flutter: ">=3.44.0"

这个坑我踩了快两小时才查到原因,官方迁移指南藏得很深。

4. HCPP:确实香,但也有坑

AGP的问题解决之后,我开始试HCPP。启用方式是在AndroidManifest.xml里加:

xml 复制代码
<application>
    <!-- 启用HCPP -->
    <meta-data
        android:name="io.flutter.embedding.android.EnableHcpp"
        android:value="true" />
</application>

或者用命令行:

arduino 复制代码
flutter run --enable-hcpp

效果确实立竿见影。之前地图页面的滑动撕裂问题完全消失了,触摸响应也快了不少。原理是HCPP不再用离屏缓冲区,而是直接把图层合成委托给Android系统,用Vulkan的硬件缓冲区交换链和SurfaceControl做同步。

但坑来了------不是所有设备都支持。HCPP对Android API级别和硬件有要求,我测试机里有台老的Android 10设备,开启HCPP后原生视图直接黑屏。文档里说了这个限制,但我一开始没注意到。

所以我加了个降级逻辑:

csharp 复制代码
import 'package:flutter/services.dart';

// 简单判断:根据API级别决定是否用HCPP
// 低于Android 12的设备自动回退
void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  final sdkInt = await _getAndroidSdkInt();
  // Android 12 (API 31)以上才启用HCPP
  if (sdkInt != null && sdkInt >= 31) {
    // HCPP已通过Manifest启用,无需额外操作
  } else {
    // 低版本设备,在Manifest里不设置EnableHcpp即可自动回退
    debugPrint('设备不支持HCPP,使用默认渲染');
  }

  runApp(const MyApp());
}

Future<int?> _getAndroidSdkInt() async {
  if (!Platform.isAndroid) return null;
  final deviceInfo = await DeviceInfoPlugin().androidInfo;
  return deviceInfo.version.sdkInt;
}

其实最简单的做法就是:AndroidManifest.xml里先不加那个meta-data,在支持的设备上通过命令行参数测试。确认没问题了再全局开启。我是测试环境直接开了,线上还没敢推。

5. Swift Package Manager:iOS端的"小"坑

3.44另一个大变化是Swift Package Manager替代CocoaPods成为iOS/macOS的默认包管理工具。Flutter CLI会自动帮你迁移Xcode项目。

但我项目里有个第三方推送SDK,它还在用CocoaPods。跑flutter build ios的时候出了警告:

kotlin 复制代码
CocoaPods is in maintenance mode. Plugin xxx does not support Swift Package Manager yet.
Falling back to CocoaPods for this plugin.

构建倒是成功了,但这个警告意味着你的项目同时用了两套依赖管理,后续维护会很混乱。

我的做法是先忍着,等那个SDK适配SPM再说。如果你是插件开发者,建议尽快适配,别等CocoaPods彻底废了才动手。

6. Dart 3.12:私有命名参数是真的香

说完了坑,说个好用的。Dart 3.12我最爱的特性是私有命名参数

以前写私有字段+公开构造参数,代码巨丑:

dart 复制代码
class UserProfile {
  final String _displayName;
  final int _loginCount;

  UserProfile({
    required String displayName,
    required int loginCount,
  })  : _displayName = displayName,
        _loginCount = loginCount;
}

现在可以直接这样写:

dart 复制代码
class UserProfile {
  final String _displayName;
  final int _loginCount;

  UserProfile({
    required this._displayName,
    required this._loginCount,
  });
}

调用方式不变,还是UserProfile(displayName: '张三', loginCount: 42),Dart会自动去掉下划线暴露给调用方。字段在类内部是私有的,API对外是干净的。

还有个实验性的主构造函数(Primary Constructors),一行搞定数据类:

arduino 复制代码
class User(String name, int age, String email);

不过还在实验阶段,得加--enable-experiment=primary-constructors才能用,生产项目我还没敢开。

7. Material和Cupertino正在解耦

这个是3.44一个容易被忽略但影响深远的架构变化------Material和Cupertino库从核心框架中冻结了 ,后续会迁移成独立的material_uicupertino_ui包。

目前不影响现有代码,但下一个稳定版会标记为Deprecated。也就是说,未来你的import会从:

arduino 复制代码
import 'package:flutter/material.dart';

变成:

arduino 复制代码
import 'package:material/material.dart';

现在不需要改什么,但要有这个心理准备。如果你项目里有大量Material组件的深度定制,可以提前关注这个跟踪issue

8. 值不值得升?

值得升的情况:

  • 项目有原生Android视图的渲染问题
  • 想用Dart 3.12的私有命名参数
  • iOS端想告别CocoaPods

可以先等等的情况:

  • 你的Android插件还没适配AGP 9
  • 项目即将发布,没时间处理兼容性
  • 项目里几乎不用原生Platform Views

我个人的结论:升了不后悔,但留足测试时间。 HCPP解决了我蹲了大半年的渲染问题,Dart 3.12也让代码清爽不少。就是AGP 9和SPM迁移需要花点时间排雷。

最后吐槽一句:Flutter官方文档更新速度还是太慢了,AGP 9的迁移指南我在官方文档里翻了半天才找到。这方面React Native确实做得更好。

相关推荐
愚者Pro4 小时前
Flutter Widget组件学习(专为 Uniapp 转 Flutter 定制)
vue.js·学习·flutter·uni-app
rocpp6 小时前
Android 相册选择与拍照接入实践:MediaStore 分页、权限适配与 FileProvider
android
白色牙膏7 小时前
Cocos Creator 2.4.x 接入 AdMob 插件的迁移实践
android
程序员老刘7 小时前
Flutter 3.44 更新要点:很重要但暂时先别升级
flutter·ai编程·客户端
我命由我123459 小时前
C++ - 面向对象 - 常成员函数
android·java·linux·c语言·开发语言·c++·算法
tryqaaa_9 小时前
学习日志(四)【php反序列化魔术方法以及pop构造配实战】
android
程序员老刘·11 小时前
Flutter版本选择指南:3.44惊艳发布但需观望 | 2026年5月
flutter·ai编程·跨平台开发·客户端开发
●VON11 小时前
鸿蒙Flutter实战:Emoji心情选择器组件
flutter·华为·harmonyos
Java小学生丶11 小时前
记录一下我的 Gradle 开发环境配置过程
android·java·gradle·maven·安卓