移动开发

Xamarin → .NET MAUI 迁移实战手册

微软已于 2024 年 5 月停止支持 Xamarin,.NET MAUI 是受支持的继任者。下面是我们在真实迁移项目中采用的手册:哪些可以顺利移植,哪些不行,以及团队最容易低估的工作量在哪里。

发布日期:2026 年 4 月 30 日 · 11 分钟阅读

微软已于 2024 年 5 月 1 日停止对 Xamarin 和 Xamarin.Forms 的支持。受支持的前进路径是 .NET MAUI(多平台应用 UI),它大体上是 Xamarin.Forms 在架构上的继任者,拥有统一的 .NET 运行时和单一项目结构。营销宣传说这是「轻松迁移」,现实则更为微妙。在完成了多个真实迁移项目之后,下面是我们采用的手册。

「迁移」到底意味着什么

第一个决定是诚实地界定范围。基于一套现有的 Xamarin.Forms 代码库,可能存在三种项目,而它们从外部看几乎一模一样:

  • 机械式移植。转换项目文件、替换命名空间、更新绑定语法,然后发布。最理想情况下:中等规模应用需要 2 至 4 周。
  • 移植加清理。在上述基础之上,再淘汰你早已知道粗糙的部分(应改为 MAUI 处理程序的自定义渲染器、应改用 Shell 的定制导航、一直勉强运转的异步代码)。需要 6 至 10 周。
  • 以重写的方式迁移。代码库累积了 5 年以上的补丁,最初的架构师已离开,而测试的现状是「每次发布前我们手动点一遍」。MAUI 正是你交付一套可持续代码库的契机。需要 12 至 24 周。

我们最常见的错误,是把本属于第三种的项目误判为第一种。探索冲刺(discovery sprint)的存在自有其道理。

哪些可以顺利移植

  • 使用标准控件的 XAML 页面。如果你的视图大多由 Label、Button、Entry、ListView 等构成,XAML 可以顺利升级。少数地方的属性名称有所变化(FormattedText → FormattedString 的层级结构不变;部分附加属性的路径有所移动)。.NET Upgrade Assistant 能捕捉到其中大部分。
  • ViewModel 和服务层。纯 C# 代码:你的业务逻辑、MVVM 绑定和 DI 注册通常无需改动即可迁移过来。
  • HttpClient 调用和 JSON 序列化。无需更改。(如果你仍在使用 Newtonsoft.Json,这是考虑改用 System.Text.Json 的好时机,不过那是一个独立的项目。)

哪些无法顺利移植

  • 自定义渲染器。Xamarin 的渲染器模型已被 MAUI 处理程序取代。概念相似,但 API 接口不同,生命周期也不同。请做好重写每一个渲染器的准备,不要指望一行代码就能替换。
  • Effects。情况相同:通常需要重建为平台特定的处理程序定制。
  • 第三方 UI 控件。能否移植取决于供应商。Telerik 和 Syncfusion 都发布了 MAUI 版本;较小的供应商往往没有。请提前盘点你的依赖项。
  • 推送通知配置。原生的 iOS/Android 配置已经发生变化(尤其是 Firebase iOS SDK 的改动)。不要想当然地认为你现有的推送代码「照样能用」。
  • 启动屏和应用图标。MAUI 拥有统一的资源模型(MauiSplashScreen、MauiIcon),这是很大的改进,但作为一次性的转换工作,常常让团队措手不及。

需要尽早做出的架构决策

Shell 还是 NavigationPage

如果你的 Xamarin 应用到处使用 NavigationPage,你可以在 MAUI 中保留这种模式,但 Shell 是新应用推荐的默认方式,并能免费带来许多好处(基于 URL 的路由、抽屉菜单、搜索)。对于我们迁移过的大多数应用,正确的做法是「v1 版本保留 NavigationPage,v2 版本再规划迁移到 Shell」。两者混用会很混乱。

单一项目还是多平台头项目

MAUI 的单一项目结构(一个 .csproj 同时支持 iOS+Android+Windows+macOS)是新的默认方式。Xamarin 则为每个平台使用单独的头项目。这种转换大体上是机械式的,但如果你有原本存放在头项目中的平台特定代码,就需要把它们重新放置到 Platforms/ 文件夹下。当团队拥有大量原生的 AppDelegate 或 MainActivity 定制时,往往会低估这部分工作。

iOS 最低版本

MAUI 的最低 iOS 版本会因 .NET 版本和应用类型而异,在你做出承诺之前,请查阅微软当前的受支持平台矩阵(最近的 .NET MAUI / MAUI Blazor 版本已分别将最低版本提升到 iOS 12.2 和 iOS 16.4,而且这个下限还在不断抬升)。如果你的 Xamarin 应用因为某些客户群体的需要而支持较旧的 iOS 版本,那么在迁移期间你将要就是否取消该支持进行一次实质性的讨论。

性能与启动

MAUI 的启动速度通常比 Xamarin.Forms 更快,在 iOS 上尤为明显。但通过在 iOS 上采用恰当的 AOT 编译以及新的 $(MtouchInterpreter) 选项,还有真正可观的收益空间。不要接受默认设置;要做性能分析并加以调优。仅靠那些无人理会的编译标志调优,我们就见到过 30% 至 50% 的启动速度提升。

迁移期间的测试

如果你的 Xamarin 应用自动化测试很薄弱甚至没有,那才是你将要暴露出来的更大问题。MAUI 在测试方面并不比 Xamarin 强出一大截。我们采用:

  • 使用 xUnit/NUnit 进行 ViewModel 和服务层测试(这些可原样移植)
  • 使用 Appium 或 MAUI 预览版基于 Hot Reload 的 UI 测试做端到端测试
  • 在迁移切换期间,在真实设备矩阵上进行手动 QA。Calvin 的经验法则是:每个受支持的操作系统大版本至少配备一台设备

切换策略

对于面向消费者的应用,你将发布单一的 MAUI 构建,在各应用商店中取代原来的 Xamarin 构建。对于设备群已知的企业/B2B 应用(销售代表应用、仓库工具),我们做过并行的 TestFlight / 内部测试通道发布:保留已安装的 Xamarin 应用,同时让一小批试点用户使用 MAUI 版本。发现了缺陷?在 MAUI 中修补即可,而不会干扰那些仍在稳定的 Xamarin 构建上的生产用户。

隐藏的成本:第三方依赖

真正会让预算失控的,是那一长串你早已忘记自己用过的第三方库。Xamarin 拥有 10 年以上的插件生态;并非其中所有插件都有兼容 MAUI 的继任者。在你签下固定价的迁移合同之前,请审计每一项 NuGet 引用。任何自 2022 年以来就没有更新过的库都是一个危险信号。

结论要点

对大多数应用而言,迁移是实打实的工作量,而非一周就能搞定的重构,介于移植和部分重写之间。好消息是:一旦迁移到 MAUI,你就站在了一个受支持、仍在积极开发、拥有未来的平台之上。坏消息是:没有人再做新的 Xamarin 项目,所以即便你的应用「还好好的」,能维护它的人才储备每个季度都在缩水。

如果你有一个 Xamarin 应用,正想评估其迁移规模,欢迎给我们留言。在报价之前,我们会先做一次真实的审计,这正是我们避免陷入「机械式移植变成重写」陷阱的方式。

免费咨询

有一个与本文相关的真实项目吗?

20 多年构建 B2B 系统的经验。我们会坦诚地告诉你,我们是不是承接它的合适人选。

877.609.9029
开启一次对话