# 小窝 App 自动更新设计

## 目标

只给两个人用，更新要少打扰、可回滚、不靠轮询、不要求用户反复手动下载安装包。

## 结论

采用两层更新：

1. 资源热更新：聊天页、样式、文案、表情包、轻量 JS 逻辑自动更新。
2. 原生包更新：涉及权限、录音、通知、数据库 schema、系统能力时再升级 APK。

Android 普通应用不能像系统应用那样完全静默安装 APK。最接近微信体验的做法是：平时资源自动更新；必须换 APK 时，应用内下载，用户点一次确认安装。

## 更新类型

### 资源热更新

适用：

- UI 样式
- 聊天页布局
- 图标、贴纸、表情资源
- 文案
- 轻量业务逻辑
- 远端配置

流程：

```text
App 启动
→ 建立 WebSocket
→ 服务端推送 latestVersion
→ App 对比本地 resourceVersion
→ 有新版则后台下载资源包
→ 校验 hash 和签名
→ 解压到新版本目录
→ 下次进入页面切换新版
→ 旧版本保留一份用于回滚
```

不使用定时轮询。版本变化通过 WebSocket 推送；断线重连后只做一次版本校验。

### 原生包更新

适用：

- 新增 Android 权限
- 录音/播放底层变更
- 通知通道变更
- SQLite schema 大升级
- WebSocket 协议不可兼容
- 崩溃修复

流程：

```text
服务端发布 apkVersion
→ App 收到版本事件
→ 判断是否强制
→ 后台下载 APK
→ 校验 sha256 和签名
→ 弹出更新卡片
→ 用户确认
→ 调起 Android PackageInstaller
→ 安装完成后自动打开 App
```

普通 Android/OPPO 手机上，最后安装步骤需要系统确认。不要绕过系统安装确认。

## 版本通道

- stable：女朋友手机默认用这个。
- beta：你自己的手机先用这个。

发布顺序：

```text
先发 beta
→ 你用半天或一天
→ 没问题再升 stable
→ 她的手机收到 stable 更新
```

## 版本元数据

```json
{
  "appVersion": "1.0.3",
  "resourceVersion": "2026.07.10.1",
  "channel": "stable",
  "minAppVersion": "1.0.0",
  "force": false,
  "apkUrl": "https://example.com/releases/xiaowo-1.0.3.apk",
  "resourceUrl": "https://example.com/releases/resource-2026.07.10.1.zip",
  "sha256": "...",
  "notes": "优化语音播放和引用交互"
}
```

## 安全要求

- 所有更新包必须走 HTTPS。
- APK 和资源包都校验 sha256。
- 资源包额外做签名校验。
- 版本只能升级，不能被远端降级，除非进入手动回滚模式。
- 保留最近一个可用资源版本。
- 更新失败不影响当前版本继续运行。

## 不轮询设计

- 新版本通知：WebSocket 事件。
- App 启动：一次版本校验。
- App 回到前台：如果距离上次校验超过 6 小时，只校验一次。
- 下载进度：本地下载任务回调。

没有每隔几秒请求服务器的轮询。

## 用户体验

资源热更新：

- 静默下载。
- 下载完成后轻提示：`小窝已更新，重新进入后生效`。
- 如果只是样式/文案，可以下次打开页面自然生效。

原生包更新：

- 普通更新：底部卡片提示，可稍后。
- 关键更新：全屏提示，但保留说明。
- 更新文案只写人话：`修好了语音播放卡住的问题`。

## 第一版建议

第一版先做：

- WebSocket 推送版本事件
- 启动时一次版本校验
- 资源包自动下载和回滚
- APK 应用内下载 + 系统确认安装
- beta/stable 两个通道

暂不做：

- 完全静默 APK 安装
- 多用户灰度系统
- 复杂 AB 实验
