从架构设计到移动体验:OWMap Android APP 的入睡优先工程哲学
从架构设计到移动体验:OWMap Android APP 的入睡优先工程哲学
北京,2026年5月22日 — OWMap 产品团队今日深度解析 Gu9 版本的技术架构与设计哲学。作为 BSL1 阶段的核心产品延伸,OWMap Android APP 不只是将网页能力移植到移动端,而是一次从产品形态到技术架构的重新定义:睡前场景中,什么是最重要的?
核心命题:工具 vs 伴侣
传统 App 的设计逻辑是功能优先:「我有哪些功能,你来用」。
OWMap APP 的设计逻辑是服务优先:「你今晚需要入睡,我来为你完成这件事」。
这个根本性转变,影响了每一个技术决策:
| 传统软件视角 | Gu9 服务视角 |
|------------|------------|
| 功能完备性(越多越好) | 服务达成率(用户实际入睡了吗) |
| 日活 / 留存 | 夜活 / 入睡成功体验率 |
| 界面探索路径 | 最短阻力路径(从打开到开始聆听 ≤ 2步) |
| 用户在 App 内停留时间 | 用户从 App 退出进入睡眠的时间 |
| 功能点击率 | 定时器自然结束率(用户睡着了,不需要手动停止) |
| 推送打开率 | 用户主动回访率(明天晚上又来了) |
Gu9 的成功标准:用户打开 → 开始播放 → 手机静置 → 定时器结束 → 用户已入睡。
定时器自然结束(无人工停止)的比率,是 Gu9 最重要的单一产品健康指标。
技术架构:共享后端、轻量前端
共享后端策略
OWMap APP 与网页版共用同一套基础设施:Next.js API Routes + Supabase 数据库,不另建后端。
这一架构决策带来三个核心优势:
- 零维护成本:APP 开发团队无需维护独立的后端服务,API 升级与网页端同步
- 账号互通:用户 Session 与网页端共享,登录状态自动同步,无需重复注册
- 数据一致性:收藏、播放历史、Brew 记录等用户数据在双端实时一致
技术栈选择(方案对比):
| 方案 | 技术栈 | 优点 | 缺点 |
|------|--------|------|------|
| A:原生 Android(Kotlin) | Kotlin + Jetpack Compose | 最佳性能 | 开发周期长,与网页端代码0复用 |
| B:Flutter | Dart + Flutter | 跨平台,性能好 | 与网页端代码0复用 |
| C:React Native + Expo | JS/TS + React Native | 与网页端共享 API 调用逻辑,组件逻辑可复用 | 地球仪3D渲染需 WebView |
| D:混合应用(Capacitor)| Ionic/Web + Capacitor | 代码最大化复用 | 性能一般 |
OWMap 选择:React Native + Expo
理由:
- 与网页端(Next.js/TypeScript)技术栈同属 JS/TS 生态,API 调用层、类型定义、业务逻辑可以复用
- Expo Go 极大降低 Android 初期调试成本,无需完整 Android Studio 环境
- 地球仪渲染使用 WebView 内嵌(与网页版相同的 Globe.gl),性能可接受
整体架构图
┌─────────────────────────────────────────────────────────────┐
│ OWMap Android APP 技术架构 │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ React Native + Expo │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Globe │ │ Player │ │ Brew │ │ │
│ │ │ Screen │ │ View │ │ Flow │ │ │
│ │ │(WebView) │ │ │ │ │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ 共享业务逻辑层(TypeScript) │ │ │
│ │ │ · API 调用封装(复用网页端 api-client.ts) │ │ │
│ │ │ · 类型定义(复用 supabase.ts) │ │ │
│ │ │ · Auth 逻辑(复用 Supabase Auth SDK) │ │ │
│ │ │ · Brew 状态机(复用核心逻辑) │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ Native 能力层 │ │ │
│ │ │ · 音频(react-native-track-player) │ │ │
│ │ │ · 后台服务(Foreground Service) │ │ │
│ │ │ · 推送(expo-notifications) │ │ │
│ │ │ · 触觉(expo-haptics) │ │ │
│ │ │ · 存储(expo-secure-store / AsyncStorage) │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↕ HTTPS │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ OWMap BSL1 后端(现有) │ │
│ │ │ │
│ │ Next.js API Routes ←→ Supabase │ │
│ │ /api/v1/bsl1/... · PostgreSQL │ │
│ │ · Auth (JWT) │ │
│ │ + 新增 APP 专用 API: · Storage │ │
│ │ /api/mobile/... · Realtime │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
核心功能架构:四层服务体系
Gu9 采用四层服务体系设计,每层对应不同的用户需求深度:
┌────────────────────────────────────────────────────────────┐
│ Gu9 助眠服务体系 │
│ │
│ L1 · 入场层(Entry) │
│ ───────────────────────────────────────────────────── │
│ · 今夜的故事(每晚21:30推送,一键进入播放) │
│ · 快速启动(冷启动≤1.5s,直接进入播放状态) │
│ · 记忆恢复(昨晚听到哪里,今晚续上) │
│ │
│ L2 · 核心服务层(Core) │
│ ───────────────────────────────────────────────────── │
│ · 故事聆听(Sleep Player Mode A:故事+音乐) │
│ · 纯音乐陪伴(Sleep Player Mode B:大洲背景音乐) │
│ · 睡眠定时器(15/30/45/60/∞,渐进淡出) │
│ · 地球仪浏览(轻量化探索) │
│ │
│ L3 · 深度服务层(Depth) │
│ ───────────────────────────────────────────────────── │
│ · Brew A(随机生成故事,给我惊喜) │
│ · 个人探索地图(我去过哪里,我听过什么) │
│ · 收藏与播放历史 │
│ │
│ L4 · 生态层(Ecosystem,与网页端联动) │
│ ───────────────────────────────────────────────────── │
│ · 账号与订阅(同步网页端状态) │
│ · Brew 内容审核通知(APP 端接收) │
│ · Earth Passport 成就系统 │
└────────────────────────────────────────────────────────────┘
睡眠播放器:三种模式背后的声学设计
Sleep Player 是 Gu9 的核心功能,提供三种差异化播放模式:
Mode A:故事 + 音乐(主服务)
叙事内容叠加大洲背景音乐,适合首次收听。用户听到故事的同时,感受所在文化圈的环境音。
技术实现:
- 主音频轨道:故事 TTS 音频(CDN 流地址)
- 背景音乐层:文化圈专属 BGM(循环,无缝衔接)
- 音量混音:背景音乐固定为故事音量的 20%(可在设置中调节)
- Karaoke 时间轴:未来支持故事文本与音频同步滚动
Mode B:纯背景音乐(环境沉浸)
无叙事内容,单纯的大洲环境音乐。适合已知故事内容或只想沉浸的用户。
音乐库设计:
- 六大文化圈各自独立音乐风格
- 每圈至少 5 首循环曲目,无缝切换
- 音量均衡:整体响度控制在 -16 LUFS(适合睡眠场景)
Mode C:文字漂浮(视觉叙事)
文字以浮动方式出现,配合背景音乐。适合视力正常但想减少音频干扰的场景。
设计要点:
- 字体大小可调(8pt-20pt)
- 漂浮速度可调(慢/中/快)
- 背景色可切换(黑/深蓝/透明)
地球仪设计:WebView 方案的务实选择
实现方式
地球仪使用 WebView 内嵌封装:将现有网页版 Globe.gl 封装为独立 HTML 页面(globe.html),随 APP 本地打包。
通信协议(WebView ↔ RN):
RN → WebView(命令):
{ type: "ROTATE_TO", lat: 31.6295, lng: -7.9811 }
{ type: "HIGHLIGHT_ICON", geoId: "MAR-001" }
{ type: "SET_GLOBE_STATE", state: "sleep" }
{ type: "SET_FILTER", types: ["folk", "history"] }
WebView → RN(事件):
{ type: "ICON_CLICKED", geoId: "MAR-001", lat: 31.6, lng: -7.9 }
{ type: "LONGPRESS_COORDS", lat: 31.6, lng: -7.9 }
{ type: "GLOBE_READY" }
性能优化:
- WebView 使用硬件加速
- 地球仪 HTML 打包为 app bundle 内 asset,无网络请求(首帧 < 800ms)
- 低端设备(RAM < 3GB)自动切换为轻量模式:降低粒子密度、关闭光影效果
后台音频:睡眠场景最关键的技术点
技术选择:react-native-track-player
这是 Android APP 最关键的技术点,也是最容易被系统省电策略破坏的功能。
核心能力:
- MediaSession 集成:锁屏界面显示播放控制
- Foreground Service:防止系统回收后台进程
- 音频焦点管理:与其他音乐 App 互斥播放
- 后台播放稳定性:连续播放 ≥ 8 小时无中断
Android 省电策略适配:
- 应用内弹窗引导用户关闭电池优化
- Foreground Service 设置为前台通知形式(最小化通知内容)
- 使用精确的 AlarmManager 定时器替代 JobScheduler(防止被延迟)
界面设计哲学:极简主义的夜晚美学
三层设计价值观
第一层:入睡优先(Sleep-First Design)
所有界面决策都通过一个测试:「这个元素在用户已经半睡着时,会制造摩擦还是减少摩擦?」
- 按钮尺寸 ≥ 56px(手指疲惫时的可靠触控目标)
- 操作层级 ≤ 2步(从任何界面到播放状态不超过两次点击)
- 无数字焦虑(不显示消息数量、未读角标、今日剩余配额倒计时)
- 无强制决策(不弹出「选一个」的对话框——给默认值,允许修改)
第二层:地理诗意(Geographic Poetry)
APP 不是工具软件——它是地球的可触摸界面。
- 地球仪是主角,不是配件
- 坐标信息是诗意的(用「北非海岸·摩洛哥」而非「30.4234°N, -9.5981°W」)
- 故事标题使用文学感强的字体(Cormorant Garamond)
- 时间感:使用「今晚」「昨夜」「这个冬季」而非「2小时前」
第三层:用户主权(User Sovereignty)
用户在地球上留下的每一个故事标记,都是有重量的。界面要让这种重量感被感知到——不轻佻,不即兴,不像刷短视频。
导航结构:单手操作的极致简化
┌─────────────────────────────────────────────────────────────┐
│ OWMap APP 结构图 │
│ │
│ ╔═══════════════════════════════════════════════════╗ │
│ ║ 底部 Tab 主导航(3个) ║ │
│ ║ 🌍 探索 📚 收藏 👤 我的 ║ │
│ ╚═══════════════════════════════════════════════════╝ │
│ │
│ 探索 Tab(Globe View) │
│ ├── 地球仪主界面(全屏) │
│ │ ├── 点击 ICON → 故事卡片浮层(底部弹出) │
│ │ └── 左滑 → 筛选面板(抽屉) │
│ └── Player View(全屏覆盖层) │
│ │
│ 收藏 Tab(Library View) │
│ ├── 收藏的故事列表 │
│ ├── 播放历史 │
│ └── 我的 Brew(已生成内容) │
│ │
│ 我的 Tab(Profile View) │
│ ├── 账号信息 + 订阅状态 │
│ ├── Brew 点数余额 │
│ └── 设置(音频、语言、深色模式) │
└─────────────────────────────────────────────────────────────┘
用户旅程:从首次使用到日常依赖
首次使用旅程(First Night)
下载 App
↓
启动画面(1.2s,地球仪缓慢旋转,Deep Space 背景)
↓
欢迎引导(3页,可跳过)
↓
快速账号设置(匿名模式可先体验)
↓
今晚推荐出现(系统根据当前时间推荐一个故事)
↓ 一键播放
Sleep Player 全屏启动(默认定时器30分钟)
↓
用户入睡 / 定时器结束 / 用户手动停止
↓
次日晚21:30推送「今夜的故事」→ 第二次回访
核心原则:
- 引导页不超过3页,可随时跳过
- 注册不是必须——匿名体验足以验证核心价值
- 第一个故事由系统决定,不让新用户面对选择(选择困难 = 退出)
日常使用旅程(Regular Night)
两种典型进入场景:
场景 A:通知进入
21:30 推送:「今夜带你去冰岛·极光传说」
点击通知 → APP 直接跳转至该故事预览卡片
一键播放 → Sleep Player 全屏
场景 B:主动打开
打开 APP(冷启动 < 1.5s)
主界面:地球仪(缓慢旋转)+ 今日精选栏
浏览或直接点击精选 → 故事预览卡片 → 播放
Sleep Player 全屏
MVP 红线:功能边界决定产品性格
Gu9 明确排除以下功能(MVP 阶段不做):
- ❌ 日间信息流(不与微信公众号争夺白天注意力)
- ❌ 社交功能(不设评论区——睡前的安静是核心资产)
- ❌ 短视频(屏幕光是睡眠的敌人)
- ❌ 闹钟(会侵蚀「助眠伴侣」的品牌定位)
- ❌ 离线下载(移至 Gu9.1)
- ❌ 精准坐标 Brew(移至 Gu9.1)
- ❌ Widget / WearOS(V2)
理由:Gu9 是服务验证版本,不是功能完备版本。每增加一个功能,冷启动时间增加,决策负担增加,入睡路径变长。
OWMap 产品团队 | 产品深度解析 · 2026年5月
Gu9 版本代号 Good Night,以服务而非软件为交付物