移动端概览 Mobile
本教程共 42 篇 · 第 41 篇 · 更新于 2026-08-03
41. 移动端概览 Mobile
本节目标
- 明确 Wails v2.13.0 的平台边界,知道移动端支持归属哪个版本线
- 了解 v3 实验性移动端的架构:WebView 选型、桥接方式、产物形态
- 知道 iOS / Android 各自缺哪些能力,判断自己的需求是否踩线
- 学会把业务代码分层,为将来可能的移动端复用留出空间
41-1 先说结论
如果你打算用本教程的基线版本做手机 App,答案很直接:Wails v2.13.0 不支持移动端。它的目标平台是 Windows、macOS、Linux 三个桌面系统,wails build -platform 能接受的取值里没有 ios 和 android。
移动端支持出现在 Wails v3 分支,并且官方明确标注为实验性(EXPERIMENTAL):API 和构建流程在正式发布前都可能大改,不建议用在生产环境。
这一章讲的内容,性质更接近「了解一下技术路线」,而不是「跟着做一遍」。之所以要讲,是因为很多人选型时会问「以后能不能顺手出个手机版」,得先知道这个「以后」大概是什么样子。
Warning本章出现的
application.New(application.Options{...})是 Wails v3 的 API,和 v2.13.0 的wails.Run(&options.App{...})完全不同。别混着写,两套 API 不通用。
41-2 移动端的架构长什么样
v3 移动端的思路和桌面端一脉相承:Go 写业务逻辑,Web 技术写界面,系统原生 WebView 负责渲染。区别在中间那层桥怎么搭。
| 平台 | WebView 组件 | 桥接技术 | 构建产物 |
|---|---|---|---|
| iOS | WKWebView | CGO(C 头文件) | .app / .ipa |
| Android | Android WebView | JNI | .apk |
CGO 是 Go 调用 C 代码的机制。iOS 上 Go 代码被编译成静态库(.a 文件),通过 C 头文件暴露给 Objective-C / Swift 侧,再由原生代码托管 WKWebView 并转发消息。
JNI(Java Native Interface)是 Java 调用本地代码的标准接口。Android 上 Go 代码编译成共享库(.so 文件),Java/Kotlin 层通过 JNI 调用它,同时负责 Android WebView 的生命周期。
两条路径的共同点是:Go 不再是主进程,而是被原生宿主加载的一个库。这跟桌面端「Go 主进程拉起 WebView」的模型正好反过来,也解释了为什么很多桌面 API 在移动端没法直接搬。
41-3 环境前置条件
想跑通实验性移动端构建,环境要求比桌面端重得多。
iOS 侧必须有 Mac。 这是苹果工具链的硬性限制,绕不过去:
- macOS 12.0 及以上
- Xcode 14.0 及以上
- Go 1.21+,且启用 CGO
- iOS SDK(随 Xcode 附带)
Android 侧三大系统都能做。 需要:
- Go 1.21+,且启用 CGO
- Android SDK(含 Platform Tools、Build Tools,模拟器可选)
- Android NDK r26d 或更新版本
- Java JDK 11+
环境变量按自己的系统配:
# macOS
export ANDROID_HOME="$HOME/Library/Android/sdk"
# Linux
export ANDROID_HOME="$HOME/Android/Sdk"
# NDK 路径按实际安装版本调整
export ANDROID_NDK_HOME="$ANDROID_HOME/ndk/29.0.14206865"
export PATH=$PATH:$ANDROID_HOME/platform-tools
export PATH=$PATH:$ANDROID_HOME/emulator
Tip装 Android SDK 最省事的方式是直接装 Android Studio,它把 SDK、Build Tools、NDK、模拟器打包装齐。只想要命令行的话,从官网下 command line tools 再用 SDK Manager 补组件。
41-4 构建与运行
v3 移动端的构建没有走 wails build,而是用 Taskfile 组织的任务。iOS 侧:
# 编译
task ios:build
# 编译并在模拟器上跑
task ios:run
# 为真机构建(需要代码签名)
task ios:build:device
背后做的事情是:把 Go 代码编成静态库 → 生成 Xcode 工程 → 调 xcodebuild 构建 → 产出 .app 包(发布时打成 .ipa)。
Android 侧:
# 默认为真机构建 arm64
task android:build
# 为模拟器构建 x86_64
task android:build ARCH=x86_64
# 打包 APK
task android:package
# 安装并运行
task android:run
# 看日志
task android:logs
流程是:Go 代码编成 .so 共享库 → Gradle 构建 Java/Kotlin 层 → 打包成 APK。
架构对应关系需要留意,选错了装到设备上会直接崩:
| Android ABI | 适用场景 | 对应 GOARCH |
|---|---|---|
| arm64-v8a | 现代设备,最常见 | arm64 |
| x86_64 | 模拟器 | amd64 |
| armeabi-v7a | 老设备,可选 | arm |
| x86 | 老模拟器,可选 | 386 |
Note报
UnsatisfiedLinkError: dlopen failed基本就是架构不匹配。真机用 arm64 重编,模拟器用 x86_64 重编。
41-5 平台差异与能力限制
前端可以在运行时判断自己跑在哪个平台上,按平台走不同分支:
const platform = window.wails.System.Platform();
if (platform === "ios") {
// iOS 专属逻辑
} else if (platform === "android") {
// Android 专属逻辑
} else {
// 桌面
}
但更重要的是知道哪些能力没有。
iOS 目前缺的:
- 系统托盘、菜单栏(移动端本来就没这个概念)
- 多窗口,只有单个全屏窗口
- 文件对话框,受 iOS 沙箱限制
- 窗口操作,位置和尺寸都改不了
Android 目前缺的:
- 系统托盘
- 多窗口,同样只有单个全屏窗口
- 文件对话框,得改用 Storage Access Framework
- 窗口操作,只有全屏
- 剪贴板只有部分支持
把这份清单对照一下前面几章的内容就会发现:第 19 到 25 章讲的窗口管理、无边框、菜单、托盘、拖放,在移动端几乎全军覆没。第 17 章的对话框也要另找方案。真正能平移的是绑定、事件、剪贴板这些不依赖窗口形态的能力。
平台配置项也是独立的一套:
// 这是 Wails v3 的实验性 API,与 v2.13.0 不兼容
app := application.New(application.Options{
Name: "My App",
Android: application.AndroidOptions{
DisableOverscroll: true,
EnableZoom: false,
UserAgent: "MyApp/1.0",
BackgroundColour: application.NewRGB(255, 255, 255),
},
})
调试上,Android 的空白 WebView 可以用 Chrome 的 chrome://inspect/#devices 连上去看,配合 task android:logs 查资源加载有没有出错。这套排查思路和第 39 章讲的桌面端白屏排查是相通的。
41-6 现在能为将来做什么
既然移动端还没稳定,与其等,不如把代码写成「以后好搬」的样子。有两条实用建议。
第一,业务逻辑不要直接依赖 Wails 运行时。 把纯计算、数据处理、网络请求这些放进独立的 package,不引用 wails/v2/pkg/runtime。绑定给前端的那层只做参数转换和调用转发:
// service/notes.go —— 纯业务,不含任何 Wails 依赖
package service
type NotesService struct {
store Store
}
func (s *NotesService) List() ([]Note, error) {
return s.store.All()
}
// app.go —— 绑定层,只做转发
package main
type App struct {
ctx context.Context
notes *service.NotesService
}
func (a *App) ListNotes() ([]service.Note, error) {
return a.notes.List()
}
这样即便将来换到 v3 或者移动端,只需要重写薄薄的绑定层。
第二,界面上把窗口相关的交互隔离出来。 自定义标题栏、托盘菜单、多窗口这些逻辑集中在少数几个组件里,不要散落在业务组件中。将来做移动版,把这几个组件换掉就行。
Tip如果移动端是明确的需求而不是「顺便」,现阶段更稳妥的做法是评估成熟的跨端方案。Wails 的强项在桌面,这一点在可预见的时间内不会变。
常见误区
以为 wails build -platform android 能用。 v2 的平台列表里没有移动端,这条命令只会报错。
把 v3 的示例代码抄进 v2 项目。 application.New 和 wails.Run 是两套完全不同的入口,混用必然编译失败。
指望桌面代码原样跑在手机上。 光是「没有多窗口、没有托盘、文件对话框受限」这三条,就足以让一个桌面工具类应用大改。
低估环境搭建成本。 NDK、JDK、SDK 版本互相牵制,第一次配通往往比写代码花的时间还多。
小结
Wails 的移动端支持存在,但停留在 v3 的实验阶段,iOS 靠 CGO + WKWebView,Android 靠 JNI + Android WebView,产物分别是 .ipa 和 .apk。当前版本 v2.13.0 专注桌面三平台。做技术选型时按现状判断,别把实验特性当成路线图承诺。真正能提前做的准备只有一件:把业务逻辑和平台能力分层,让代码将来搬得动。下一章收尾,聊聊模板、社区和一个真实项目的结构。