外观
Android 版本更新功能
自建版本更新系统。
deploy.sh一键构建→发布,后端 API 提供检查/下载/发布,首页自动检测 + 设置页手动检查。下载通过AppUpdateBanner管理,含进度+速率+FileProvider 安装。
1. 架构
deploy.sh (本地/服务器)──scp/OSS──→阿里云 OSS + 服务器本地目录
│
└──POST /api/app/update/publish──→system_settings + app_updates
Android App ──GET /api/app/update/check──→后端
──GET /api/app/download/{name}──→后端(本地文件流)2. 涉及文件
| 端 | 文件 | 说明 |
|---|---|---|
| deploy | codenote-android/deploy.sh | 一键发布脚本 |
| 后端 | AppUpdateController.kt | 检查/下载/发布/版本列表 4个接口 |
| 后端 | AppUpdate.kt (Entity) | app_updates 表实体 |
| 后端 | AppUpdateResponse.kt (DTO) | 检查更新响应模型 |
| 后端 | AppPublishRequest.kt (DTO) | 发布请求模型 |
| 后端 | AppUpdateRepository.kt | JPA 仓库 |
| 后端 | AdminController.kt | GET /api/admin/app-updates 历史 |
| 后端 | SecurityConfig.kt | /api/app/** 公开 |
| Android | ApiService.kt | checkAppUpdate() |
| Android | AppUpdateResponse | 网络响应模型 |
| Android | AppUpdateInfo | 领域模型 |
| Android | Repositories.kt + RepositoryImpls.kt | checkUpdate() |
| Android | DataModule.kt | Hilt 注入 |
| Android | AppUpdateBanner.kt (core/ui) | 下载组件:版本提示→进度+速率→安装 |
| Android | SettingsScreen.kt | 设置页「检查更新」按钮 → 弹 AppUpdateBanner |
| Android | HomeScreen.kt + HomeViewModel.kt | 首页自动检测 → 显示 AppUpdateBanner |
3. 数据存储
3.1 当前版本(system_settings)
| key | 说明 |
|---|---|
app.latest_version_code | 最新版本号(Int 比较) |
app.latest_version_name | 最新版本名 |
app.download_url | 下载地址(API 代理,非 OSS 直链) |
app.file_size | APK 大小(字节) |
app.release_notes | 更新日志 |
app.is_major | 是否大版本(1=弹窗不可关闭) |
app.force_update | 是否强制更新 |
判断规则: is_major=1 或 force_update=1 → 弹窗不可关闭;否则可关闭。
3.2 发布历史(app_updates)
每次 deploy.sh INSERT 一条记录,不覆盖。管理后台 GET /api/admin/app-updates 倒序查看。
4. 发布流程(deploy.sh)
4.1 前置条件
JDK 17 + Android SDK + 签名文件 codenote.jks + 服务器 Python3 oss2。
4.2 执行
bash
./deploy.sh # 手动:输入版本号、日志、isMajor、forceUpdate
./deploy.sh --auto # 自动:API 获取最新版本,patch +14.3 脚本流程
| 步骤 | 说明 |
|---|---|
| 1 | 查询 API GET /api/app/update/versions 展示最近 3 个版本 |
| 2 | 读取 version.properties(或 API 最新版本),确定新版本号 |
| 3 | 修改 version.properties 版本号 |
| 4 | ./gradlew assembleRelease 构建(含签名+对齐) |
| 5 | scp → 服务器 /tmp/(开发机)或本地直传(服务器端) |
| 6 | Python oss2 上传 OSS(public-read)+ 复制到服务器 apk/ 目录 |
| 7 | POST /api/app/update/publish 写入 system_settings + app_updates |
| 8 | git commit version.properties → git push |
| 9 | 手动模式创建 git tag v{x.y.z} |
4.4 下载地址
客户端实际使用 API 代理下载:
https://api.la998.com/api/app/download/codenote-v{versionName}.apk后端从服务器 apk/ 目录返回文件流。OSS 仅作备份。
5. 后端 API
5.1 检查更新(公开)
GET /api/app/update/check?versionCode={currentCode}返回 AppUpdateResponse(hasUpdate/versionCode/versionName/downloadUrl/fileSize/releaseNotes/isMajor/forceUpdate)。不需要登录。
5.2 下载 APK(公开)
GET /api/app/download/{fileName}后端以 application/octet-stream 返回本地文件。不存在返回 404。
5.3 发布(内部调用)
POST /api/app/update/publishBody: AppPublishRequest(versionCode/versionName/downloadUrl/fileSize/releaseNotes/isMajor/forceUpdate)。更新 system_settings + 写入 app_updates。仅 deploy.sh 调用。
5.4 版本列表(公开)
GET /api/app/update/versions → 最近 3 条 app_updates(给 deploy.sh 展示)
GET /api/app/update/latest → 最新 1 条 app_updates(给 deploy.sh 自动模式)5.5 管理后台(需管理员)
GET /api/admin/app-updates → 全部 app_updates 倒序6. 管理后台
入口:侧边栏 → 系统设置。「版本管理」卡片显示当前版本信息,「版本历史」表格显示所有发布记录。不提供发布功能。
7. Android 客户端
7.1 接入点
| 入口 | 方式 | 状态 |
|---|---|---|
| 首页 | HomeViewModel.init() 自动检查 | ✅ 首页显示 AppUpdateBanner |
| 设置页 | 点击「检查更新」按钮 | ✅ 手动触发 |
7.2 检查逻辑
PackageManager获取当前versionCodeGET /api/app/update/check?versionCode=xxx- 无更新 → 静默 / Toast "已是最新版本"
- 有更新 → 首页显示
AppUpdateBanner/ 设置页弹更新栏
7.3 下载与安装
AppUpdateBanner提供更新入口- 点击"点击更新" →
DownloadManager下载(VISIBILITY_VISIBLE_NOTIFY_COMPLETED) - 轮询
DownloadManager.Query更新进度条+速率(每 500ms) - 下载完成
ACTION_DOWNLOAD_COMPLETE→FileProvider.getUriForFile→Intent.ACTION_VIEW安装
8. 发布后验证
打开 App → 首页自动提示更新;或设置页点击"检查更新"。isMajor/forceUpdate=1 弹窗不可关闭,否则可关闭。
9. 后续
- 差分包:APK > 80MB 时引入 bsdiff