为什么 AI 更擅长开发 Web,却搞不定 App
用 Cursor、Windsurf、GitHub Copilot 写过代码的人应该都注意到了:让 AI 写一个 React 页面,几分钟就搞出来,效果还不错。但让它写一个 Android App,出来的东西总是差点意思——要么布局对不齐,要么生命周期处理有问题,要么 Gradle 配置报错。
这不是你的 Prompt 写得不好。这是 Web 开发和移动端/桌面端开发在本质上有差异,而这些差异恰好决定了 AI 的能力边界。
问题根源:AI 擅长什么
先搞清楚 AI 写代码是怎么工作的。LLM 的训练数据是数亿个代码文件和文档。它根据你给的上下文预测下一段代码应该是什么。
这意味着它的能力完全取决于两个因素:
- 训练数据里有没有足够多的高质量示例
- 代码的正确性在文本层面能不能直接判断
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 模型本身。
瓶颈在于:
- 编译反馈链路太长。 改了代码 → 编译(几十秒)→ 装到设备(几十秒)→ 运行 → 发现问题 → 回到原点。这个循环比 Web 的"保存 → 刷新 → 看到结果"慢了一个数量级。
- 错误信息不够结构化。 Gradle 的报错经常是几百行的堆栈信息,真正有用的就一行。AI 处理这种噪音信息效率很低。
- 视觉反馈难以文本化。 一个按钮偏了 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 项目你得坐稳驾驶座。