Flutter 适配新 Android API 级别(New Android API Level)的完整维护指南
【免费下载链接】flutterFlutter makes it easy and fast to build beautiful apps for mobile and beyond项目地址: https://gitcode.com/GitHub_Trending/flutter41/flutter
每年 Android 都会在秋季与春季发布新的 API 级别,而 Flutter 开发者期望在新版本可用后第一时间基于它构建应用。本文以 New-Android-version.md 为核心骨架,系统梳理 Flutter 仓库从"新版 Android 发布"到"Flutter 全链路适配"所需的全部工作项:从调研破坏性变更、升级 Robolectric、把 Android SDK 上传到 CIPD,到引擎与模板的 SDK 版本提升、AVD 与真机测试环境的更新等。读完本文,你将掌握一套可逐年复用的 Android API 升级 SOP,并能在本仓库中定位每一个对应的实现文件与配置。
一、适配新 Android API 级别的目标与整体策略
1.1 为什么每年都要做这件事
每当 Android 发布新的 API 版本,Flutter 都必须保证 Android 上的 Flutter 应用能在该新版本上继续成功构建。达成目标的两条主线分别是:
- 处理新 API 引入的行为变更(behavioral changes)与破坏性变更(breaking changes)——这部分工作内容逐年不同,取决于该版本 Android 的具体改动;
- 更新基础设施以针对新 API 做测试——更新 Flutter on Android 的 CI,这部分流程每年基本一致,可以沉淀成标准操作。
文档同时给出一个重要建议:按顺序执行下面的步骤,如果某一步被阻塞(例如上游尚未发布支持新 API 的依赖),就跳到下一步继续,不必死等。此外该文档本身也需要与时俱进,维护者应持续更新其中记录的流程、Issue 与 PR。
1.2 总体工作流一览
适配工作大体包含以下工作区(后文逐一展开):
- 创建升级到新 API 的 umbrella(伞形跟踪)Issue;
- 调研新版 Android 功能与破坏性变更;
- 提升仓库内 samples 的 compile/target SDK;
- 更新 Robolectric 版本;
- 更新本地工具链、模拟器与真机到新 API;
- 将新 Android SDK 及相关依赖上传至 CIPD;
- 更新 SDK 与依赖版本支持(CI、packages、引擎、模板、既有 App);
- 在 Firebase Test Lab 与内部真机实验室中添加新 API 设备;
- 更新 Flutter 管理的模拟器 AVD 镜像;
- 必要时升级 CI 中的 Java LTS 版本;
- 更新文档与
integration_test示例。
二、前期准备:Umbrella Issue 与功能调研
2.1 创建伞形跟踪 Issue
为"升级到新 API"创建一个 umbrella Issue 用于串联所有子任务与 PR。原文档给出过从 API 35 升级到 API 36 的跟踪示例(flutter/flutter issue #163071)。跟踪 Issue 中应覆盖上文的每一步,便于社区与团队按链接定位进展。
2.2 调研新版 Android 特性与潜在影响
新版 Android 的特性可能给 Flutter 带来破坏性或行为上的变更,工作量跨度很大。Flutter Android 团队应逐项调研新 API 特性,判断哪些是no-op(无需处理)、哪些需要实际投入开发。在实践中,团队通常对新版本的破坏性变更已有所预判,会提前排期,因此这一步的产出是"要不要做、做什么"的决策清单。
2.3 提升 samples 的 compile/target SDK
仓库中的 samples(尤其是 add-to-app 这类示例)代表最早一批采用新 Android API 的用户画像,因此要优先把它们的 compile SDK 与 target SDK 提升到新版本。这一阶段以 flutter/samples 仓库的改动为主,起到"探路"作用。
三、更新 Robolectric 测试依赖
Robolectric 是一个允许我们在本地开发机上、无需真实 Android 设备即可针对 Android API 编写单元测试的依赖。升级流程为:
- 查看 Robolectric 官方 release notes,确认是否有支持新 Android API 的版本。如果尚未发布,则此步被阻塞,直到新版本发布才能继续;
- 在
flutter/flutter(含 engine)与flutter/packages中查找所有 Robolectric 用法并逐一更新到新版本。
在本仓库中,Robolectric 驱动的宿主工程测试主要位于 dev/integration_tests/android_engine_test、dev/integration_tests/android_semantics_testing 等基于 Gradle 的 Android 测试工程中,升级时可参照这些工程内对robolectric依赖的引用做全局检索(例如搜索robolectric)以确认改动范围。
四、更新本地工具链与测试设备
更新本地开发与测试设施是验证新 API 的前提:
- 升级 Android Studio到支持新 API 的版本;
- 新增至少一台运行新 Android API 的模拟器用于测试;
- 将至少一台物理设备升级到新 Android API用于测试。
具体版本要求以官方发布的 New Android API release notes 为准。
五、将新 Android SDK 上传到 CIPD(关键步骤)
Flutter 通过 CIPD 保存一份稳定、可归档的 Android SDK 副本,engine 与 LUCI recipes 都依赖这些 CIPD 包。上传脚本位于本仓库 create_cipd_packages.sh。
5.1 权限与安全须知
- 上传 CIPD 包需要
flutter-cipd-writers角色,授予后需运行cipd auth-login刷新可用角色; - 上传到 CIPD 前务必核对文本文件中的 SDK 配置;
- 上传操作难以撤销,务必谨慎。若确实需要移除已上传的 CIPD tag,需走对应的内部 playbook 流程;
- 不要手工逐个上传新版 Android API 到 CIPD,应统一使用仓库脚本。
5.2 packages.txt:声明要打包的 SDK 组件
需要打包的 SDK 组件声明在 packages.txt,每行格式为:
<package_name>:<subdirectory_to_upload><package_name>使用sdkmanager的包标识(如platforms;android-36、build-tools;36.1.0、ndk;28.2.13676358),通常更新到最新可用版本,可用sdkmanager --list --include_obsolete查询(sdkmanager位于 Android SDK 的commandline-tools中);<subdirectory_to_upload>表示该包在 SDK 目录中需要上传的子目录(如platforms、build-tools、cmdline-tools);冒号后的子目录也可用额外:分隔声明多个;- 同一组件需要上传多个版本时用逗号分隔,例如本仓库当前配置保留了对 android-34 至 android-37 多个平台的归档:
platforms;android-37.0,platforms;android-36,platforms;android-35,platforms;android-34:platforms cmdline-tools;latest:cmdline-tools build-tools;37.0.0,build-tools;36.1.0,build-tools;36.0.0,build-tools;35.0.0,build-tools;34.0.0,build-tools;33.0.1:build-tools platform-tools:platform-tools cmake;3.22.1:cmake ndk;28.2.13676358:ndk5.3 执行上传脚本
在脚本目录下执行:
cd tools/android_sdk && ./create_cipd_packages.sh <your-tag-version> <your-local-sdk-path>脚本行为要点(可从 create_cipd_packages.sh 源码确认):
- 参数一
<your-tag-version>只能包含小写字母与数字(例如37v2),它既是 CIPD 的-tag version:,也会被用作-ref引用名; - 参数二为本地 SDK 目录,省略时默认取环境变量
ANDROID_SDK_ROOT; - 运行前要求
cipd在 PATH 中(需 depot_tools),SDK 内需已安装cmdline-tools(默认优先使用cmdline-tools/latest/bin/sdkmanager,找不到时会自动搜索其它版本); - 支持
./create_cipd_packages.sh list直接列出所有可用包(等价于执行sdkmanager --list --include_obsolete); - 脚本会为linux / macosx / windows三平台分别创建临时干净 SDK 目录,逐个按 packages.txt 安装组件,把声明的子目录与许可文件复制到上传目录,再以
cipd create上传为flutter/android/sdk/all/<platform>-<arch>(macOS 额外上传 arm64 版本以支持 M1 机器,linux/windows 只上传 amd64);完成后清理临时目录。
上传完成后,为 SDK 配置改动提交一个 PR 留存"paper trail"——虽然上传本身不依赖该 PR 合并,但能让后续维护者无需反查 CIPD 历史即可看到 SDK 配置的演进。
说明:脚本已在内部取代手工上传。若万不得已需手工上传单个包,可用
cipd create -in <your-android-dir>/Android/sdk/<some_package> -name flutter/android/sdk/<some_package> -tag version:<new-version-tag>(典型<your-android-dir>位于~/Library/Android),新 tag 将用于在DEPS中引用。
5.4 在 DEPS 中切换到新版本 tag
engine 顶层 DEPS 中即是通过 CIPD 版本 tag 拉取 Android SDK 与 Gradle 的。仓库当前示例:
'engine/src/flutter/third_party/gradle': { 'packages': [ { # Version here means the CIPD tag. 'version': 'version:9.3.1', 'package': 'flutter/gradle' } ], ... }, 'engine/src/flutter/third_party/android_tools': { 'packages': [ { 'package': 'flutter/android/sdk/all/${{platform}}', 'version': 'version:37v2' } ], ... }升级 SDK 时把flutter/android/sdk/all/${{platform}}的version改为新上传的 tag(例如version:30r2这种命名风格),必要时同步上调flutter/gradle对应的 Gradle 版本 tag。
六、更新 SDK 与依赖版本支持(落地到 CI 与产物)
新版本 Android 通常会附带新的依赖版本下限。升级顺序有讲究:先改内部测试用 App 与 ci.yaml(不直接影响用户)→ 再改 Flutter 模板(直接影响新建应用)。
6.1 更新 ci.yaml 中的 android_sdk
在flutter/flutter与flutter/packages的ci.yaml中把android_sdk版本提升到新 SDK;如果必须同时测试新版 Java,也要一并更新 ci.yaml。仓库中关于引擎/框架的 CI 配置可参见根目录的ci.yaml及 dev/README.md 相关说明,实际改动时以最小化、只涉及版本号为准。
6.2 更新 Flutter Android packages 默认值
- 让 packages 仓库的示例工程以新 API 构建;
- 更新
create_all_packages工具,使其以新 API 作为 compile SDK(对应 flutter/packages 仓库中script/tool/lib/src/create_all_packages_app_command.dart内 compileSdk 的设置逻辑)。
6.3 更新 Flutter Android 引擎默认值(含文件级清单)
当新 API 出现后,需按下表修改引擎内文件,使引擎针对新 API 编译并以其为 target(注意:仅完成编译目标并不保证新 API 下一切行为正常):
| 文件(仓库相对路径) | 修改内容 | 当前仓库参考行 |
|---|---|---|
| DEPS | flutter/android/sdk/all/${{platform}}的version改为新上传的 CIPD tag | 当前为version:37v2 |
| DEPS | 必要时把flutter/gradle版本 tag 提升到更新的 Gradle | 当前为version:9.3.1 |
| gen_javadoc.py | classpath中对android-XX的引用提升到最新版本 | 当前引用android-36 |
| android_embedding_bundle/build.gradle | compileSdk = XX提升到最新版本 | 当前compileSdk = 36 |
| shell/platform/android/test_runner/build.gradle | compileSdk = XX提升到最新版本 | 当前compileSdk = 36 |
| shell/platform/android/AndroidManifest.xml | android:targetSdkVersion=XX提升到最新版本 | 当前targetSdkVersion="36" |
| native_activity.gni | android_buildtools中build-tools/XX与android_jar中android-XX提升到最新 | 当前引用build-tools/36.1.0与platforms/android-36/android.jar |
由于该清单可能过时,实际改动时应全局搜索仓库内所有build.gradle中对旧 SDK 版本的引用,一并提升到最新版本。
6.4 更新仓库内所有既有 Flutter on Android App
- 查看新 API release notes 获取依赖版本下限;
- 更新相应 App 的构建依赖(新 API 与新依赖版本),覆盖
flutter/flutter与flutter/packages下的示例与集成测试工程。本仓库中此类工程集中在 dev/integration_tests 下,例如 flavors、release_smoke_test 等,可对照其build.gradle(或build.gradle.kts)里的compileSdk/targetSdk进行验证。
6.5 更新 Flutter Android 模板
模板直接决定用户flutter create新建工程的默认配置,影响面最大,务必最后执行:
- 查看新 API release notes 确定依赖版本下限;
- 提交一个 PR 把模板切换到新 API 与新依赖下限;此改动不要动模板的
targetSdk(可能还需要额外的 infra 变更); - 上一步合入且post-submit 检查连续 100 个 commit 不 flaky 之后,再开一个新 PR 更新
targetSdk。
模板更新后(即使尚未合并任何内容),新建的 Flutter App 就应带上新版本号。合并前必须做冒烟验证,命令如下:
flutter create <new-app-name> flutter analyze --suggestions # 检查依赖版本兼容性 flutter build apk # 确保应用能成功构建七、接入新真机与 AVD 测试环境
7.1 Firebase Test Lab 中的真机/模拟器
Firebase Test Lab 的设备支持由 Firebase 团队维护。查看是否已有新 API 物理设备可用:
gcloud firebase test android models list框架(framework)CI 仅针对物理设备做专项测试;若设备尚未上线则需等待或与 Firebase 团队协调。
7.2 更新 Flutter 管理的 AVD(模拟器镜像)
Flutter 管理的 engine 模拟器需要支持新 API 的新 AVD 镜像,并且 framework、engine、packages 三处应使用同一个 AVD。更新步骤:
- 在 Chromium 托管的 AVD CIPD(
chromium/tools/android/avd/linux-amd64/)中找到最新上传的 AVD,确认其包含目标 API 对应的generic_android_<API#>.textpb; - 记录其 instance identifier;
- 更新模拟器配置,例如在
.ci.yaml(framework 内)中把依赖指向新 AVD:
linux_android_emu: properties: contexts: >- [ "android_virtual_device" ] dependencies: >- [ ... {"dependency": "android_virtual_device", "version": "android_<API#>_google_apis_x64.textpb"}, {"dependency": "avd_cipd_version", "version": "build_id:<Instance ID>"}, ]Flutter 使用 Chromium 提供的 AVD。若新 AVD 在 post-submit 测试中失败,需与 Chromium 协作定位(通常他们会发布带修复的 revision)。为了提前验证(dogfood),可以新建一个测试平台配置,并把失败用例先加入bringup。
7.3 实验室物理设备分批升级
Flutter 维护着一批用于测试上架 App 的 Android 物理设备,升级到新 API 需要向 lab manager 提 ticket:
- 部分设备可立即升级到新 API(或支持新 API 的系统),部分需要等待设备厂商发布支持版本,届时再跟踪 release notes 并提 ticket;
- 不要一次性提交升级所有设备的 ticket:必须保证每个测试池仍有足够设备承载测试,应分批进行;
- 对已到生命周期终点、永远无法支持新 API 的设备,应选择规格相当的替代机型。
八、Java LTS 版本与文档、integration_test 收尾
8.1 升级 CI 中的 Java 版本(仅针对 Java LTS 发布)
每几年 Java 会发布新的 LTS 版本,并逐步成为行业标准(往往也随新版 Android SDK 被用户采用)。此时应把 CI 升级到新 Java 以提前暴露兼容性问题:
- 参照 Uploading-New-Java-Version-to-CIPD.md 中的指引,把新 Java 版本包上传到 CIPD;
- 更新 CI 中对当前 Java 版本的所有引用到新版本。
8.2 更新支持平台文档
适配完成后,需要同步更新官网 "supported platforms" 文档页面(docs.flutter.dev/reference/supported-platforms),明确新 API 已进入 Flutter 的测试范围。
8.3 测试integration_test包
integration_test是随 Flutter 工具发布、用于在 App 上运行集成测试的包。要确保它在最新发布的 stable Flutter 工具上,存在一个以新 API 级别为 target 的示例工程(本仓库中integration_test的示例代码位于 packages/integration_test/example)。
九、相关文档与进一步阅读
- Uploading-New-Java-Version-to-CIPD.md:把新 Java 版本上传到 CIPD 的分步指引;
- Update-Android-MinSdkVersion.md:提升 Flutter Android 最低 SDK(minSdk)版本的配套流程;
- Uploading-New-Gradle-Version-to-CIPD.md:Gradle 新版本上传到 CIPD 的配套指引;
- Emulators for Flutter Android Testing:面向模拟器的 Android 变更测试方法(与此文档配套的公开版说明);
- 引擎侧 SDK 打包脚本与配置:create_cipd_packages.sh、packages.txt。
十、总结:一份可逐年复用的检查清单
- 创建新 API 升级 umbrella Issue;
- 调研新特性,判定 no-op 与需处理项;
- samples(尤其 add-to-app)提升 compile/target SDK;
- 更新 Robolectric(确认上游已发布支持版本);
- 升级 Android Studio、模拟器与真机;
- 通过
create_cipd_packages.sh上传新 SDK 并提交 packages.txt 变更 PR; - 更新 DEPS 中 SDK/Gradle tag、引擎内各 build.gradle 与 Manifest 的 compile/target SDK;
- 更新 ci.yaml、packages 默认值与全部既有测试 App;
- 分两步更新 Flutter 模板(先版本下限,稳定后改 targetSdk),并用
flutter analyze --suggestions与flutter build apk冒烟验证; - Firebase Test Lab 真机就绪并更新 AVD 至新 API(三端统一);
- 实验室真机分批升级(保留各池测试余量);
- Java LTS 发布时同步升级 CI 并更新 CIPD;
- 更新 supported-platforms 文档与 integration_test 示例。
按此清单推进,即可在每年 Android 新版本发布后,让 Flutter 的框架、引擎、packages 与模板快速、安全地完成新 API 级别的适配与回归验证。
【免费下载链接】flutterFlutter makes it easy and fast to build beautiful apps for mobile and beyond项目地址: https://gitcode.com/GitHub_Trending/flutter41/flutter
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考