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_ui和cupertino_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确实做得更好。