为什么 AI 更擅长开发 Web,却搞不定 App

用 Cursor、Windsurf、GitHub Copilot 写过代码的人应该都注意到了:让 AI 写一个 React 页面,几分钟就搞出来,效果还不错。但让它写一个 Android App,出来的东西总是差点意思——要么布局对不齐,要么生命周期处理有问题,要么 Gradle 配置报错。

这不是你的 Prompt 写得不好。这是 Web 开发和移动端/桌面端开发在本质上有差异,而这些差异恰好决定了 AI 的能力边界。

问题根源:AI 擅长什么

先搞清楚 AI 写代码是怎么工作的。LLM 的训练数据是数亿个代码文件和文档。它根据你给的上下文预测下一段代码应该是什么。

这意味着它的能力完全取决于两个因素:

  1. 训练数据里有没有足够多的高质量示例
  2. 代码的正确性在文本层面能不能直接判断

Web 开发在这两点上占据绝对优势。

Web 开发的天然优势

海量公开训练数据。 GitHub 上 JavaScript/TypeScript 的仓库数量是 Kotlin/Java Android 仓库的几十倍。React、Vue、Next.js 的示例代码满天飞。每个问题在 Stack Overflow 上都有几十个解答。AI 见过的 Web 代码量是天文数字,所以它"猜"得准。

文本即结果。 Web 开发的输入输出都在文本层面。HTML 是文本,CSS 是文本,JS 是文本。你写一段 JSX,AI 补全一段 JSX,不需要编译器参与就能判断对不对。代码写完,浏览器打开就能看到效果——反馈闭环极短。

框架高度标准化。 React 的写法全世界几乎一样。Vue 的 SFC(单文件组件)格式是死的。Tailwind CSS 的 class 组合是可枚举的。这套标准化程度让 AI 能精准预测你下一行写什么。

调试信息完全文本化。 浏览器控制台的报错信息、网络请求的响应、DOM 结构——全是文本。AI 能读取这些文本信息,理解问题所在,然后给出修复方案。

移动端开发为什么难

编译系统的复杂性。 Android 项目的构建靠 Gradle——一个让人类开发者都头疼的构建系统。依赖冲突、版本不兼容、ProGuard 混淆规则——这些问题不会在代码里直接体现出来。AI 看到的是干净的 Kotlin 代码,但编译器报的错误可能跟代码本身毫无关系,而是 Gradle 脚本深处的某个版本号错了一个小数点。

布局系统的非确定性。 一个 Android 布局在不同屏幕尺寸、不同分辨率、不同系统版本上表现不同。ConstraintLayout 的约束关系、LinearLayout 的权重计算、RecyclerView 的复用机制——这些不是纯文本逻辑能表达的。

你写 android:layout_width="match_parent"——这段文本本身没问题,但它在 6 寸屏和 10 寸屏上的实际效果完全不同。AI 看不到实际渲染结果,它只知道文本层面写对了。

生命周期的隐式复杂性。 Android 的 Activity/Fragment 生命周期有几十个回调方法。屏幕旋转、切后台、内存不足回收——这些场景的组合让状态管理变得极其复杂。AI 很难在没有运行环境的情况下推理"用户按下 Home 键 → 系统回收 Activity → 用户返回"这条路径上每个回调的执行顺序。

平台 API 碎片化。 Android 有几十个版本,每个版本有不同的 API Level。Camera API 在 API 21 和 API 28 上完全不同。权限模型从 Android 6 到 Android 13 改了四五版。AI 的训练数据里混杂了各个版本的写法,它很难判断"在 2025 年的最佳实践是什么"。

传感器和硬件的介入。 相机、GPS、蓝牙、NFC——这些硬件能力的调用涉及系统服务绑定、权限检查、回调注册。AI 只能写出"看起来对"的代码,但在真机上能不能跑——它不知道,也没法验证。

桌面应用的类似困境

Windows 桌面开发的问题和 Android 很像,甚至更严重。

框架碎片化。 你想写一个 Windows 桌面应用,选什么?WPF、WinForms、UWP、WinUI 3、MAUI、Electron、Tauri、Qt——光列出来就八个。每个框架的写法完全不同,训练数据被严重稀释。

AI 对 WPF 的 XAML 布局略有了解,对 WinForms 的事件模型也知道一点,但没有任何一个框架的训练数据多到让它能像写 React 一样稳定输出。

UI 渲染的复杂性。 WPF 的依赖属性系统、资源字典、DataTemplate、ControlTemplate——这些概念在 Web 开发里没有对应物。Web 的"组件"概念在 WPF 里是 UserControl/CustomControl,但机理完全不同。

COM 和 Win32 API 的历史包袱。 很多"基础操作"在 Windows 上需要通过 P/Invoke 调用 Win32 API。这些 API 的文档质量参差不齐,参数类型靠 IntPtr 传递,内存管理得手动处理——AI 很难在缺少上下文的情况下写出正确的 P/Invoke 签名。

最直接的对比

我分别用 AI 做了一个同样功能的 Web 版和 Android 版,感受差距很具体:

Web 版(React + Tailwind):

  • 描述功能 → AI 生成页面 → 浏览器预览 → 有小问题 → AI 修复 → 十分钟完成
  • 出现问题 AI 能自动读取控制台报错,精准定位

Android 版(Kotlin + Jetpack Compose):

  • 描述功能 → AI 生成代码 → 编译报错 → 把报错贴给 AI → AI 修改 → 编译通过 → 安装到模拟器 → 布局错位 → 描述"那个按钮跑到屏幕外面了" → AI 猜着改 → 再编译 → 再安装 → 另一个问题
  • 整个过程循环五六次,半小时过去了

差距不在于 AI 聪明不聪明——在于每一步的反馈速度和信息密度。Web 的反馈是即时的、文本化的。Android 的反馈是延迟的(编译+安装)、视觉化的(很难用文本描述 UI 问题)。

AI IDE 也在进步,但瓶颈不在 AI

Cursor、Windsurf 这些工具在持续改进对移动端开发的支持。但是说实话,瓶颈不完全在 AI 模型本身。

瓶颈在于:

  1. 编译反馈链路太长。 改了代码 → 编译(几十秒)→ 装到设备(几十秒)→ 运行 → 发现问题 → 回到原点。这个循环比 Web 的"保存 → 刷新 → 看到结果"慢了一个数量级。
  2. 错误信息不够结构化。 Gradle 的报错经常是几百行的堆栈信息,真正有用的就一行。AI 处理这种噪音信息效率很低。
  3. 视觉反馈难以文本化。 一个按钮偏了 5dp——这种问题你能看到,但很难用文字准确描述给 AI。

该怎么做

认清现实,现阶段最好的策略是:

Web 开发放给 AI。 页面布局、表单逻辑、API 对接、样式调整——让 AI 主力输出,你审查和微调。效率提升非常明显。

移动端/桌面端你主导,AI 辅助。 你负责架构设计、组件拆分、状态管理方案、编译配置。AI 帮你写单个函数、补全模板代码、生成单元测试。把 AI 当高级自动补全,而不是全权委托的工程师。

跨平台是把双刃剑。 React Native 和 Flutter 让移动端开发更接近 Web 的开发体验,AI 对这些的支持也确实更好。但它们终究要打包成原生 App,编译、调试、上架的流程一个都少不掉。AI 能帮你写好 UI 层,但底层的原生问题还是得人来解决。

最后

AI 擅长 Web 开发不是因为它更懂 Web——是因为 Web 开发的反馈循环更适合 AI 的工作方式。

当某天 AI 能直接操控 Android 模拟器,看到渲染结果,自动修正布局——那时候移动端开发也会变得和今天 Web 开发一样高效。但在那之前,移动端和桌面端开发仍然需要人的判断力。

至于现在——Web 项目放心交给 AI,App 项目你得坐稳驾驶座。

一名痴迷于计算机技术的学生~