app自動更新
This commit is contained in:
1 parent
31de6c4cd6
commit
699a26371a
7 files changed
+614
-156
No files matched your search
@@ -0,0 +1,98 @@
|
||||
# App 自检更新(静态版本清单 + APK 整包,一期)
|
||||
|
||||
适用范围:`src/utils/appUpdate.ts`、`src/App.vue`、`src/pages/tab/mine.vue`、`src/manifest.json`(Android 权限),以及 `D:\Net8\FileServer` 下的 `app-update.json` + `youjiala.apk` 两个发布物。
|
||||
|
||||
本文只讲「App 怎么发现自己有新版本并装上」。文件地址怎么变成端上可达的 URL 见 [file-url.md](./file-url.md),接口地址与线路分层见 [environment.md](./environment.md)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 一句话结论
|
||||
|
||||
FileServer 根目录放一份 `app-update.json`(版本清单)和 `youjiala.apk`(整包),**零后端代码改动**:App 启动后延迟静默查一次、「我的 → 检查更新」可手动再查,发现新版走「弹窗 → 下载整包 → 拉起系统安装器」。发版 = 替换 apk + 改 json,两步完成。
|
||||
|
||||
## 2. 版本清单格式(`FileServer/app-update.json`)
|
||||
|
||||
```json
|
||||
{
|
||||
"versionCode": 1,
|
||||
"versionName": "1.0.0",
|
||||
"description": "首个正式版本:家庭相册、家族树与文档共享。",
|
||||
"descriptionEn": "First release: family albums, genealogy trees and document sharing.",
|
||||
"force": false,
|
||||
"apk": "youjiala.apk"
|
||||
}
|
||||
```
|
||||
|
||||
| 字段 | 必填 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `versionCode` | ✅(缺/为 0 视为坏清单,检查直接判失败) | **唯一比较依据**,与 `manifest.json` 的 versionCode 同口径的自增号 |
|
||||
| `versionName` | 建议 | 弹窗标题展示用;缺失时回落显示 versionCode |
|
||||
| `description` / `descriptionEn` | 可选 | 更新说明,按当前界面语言取,英文缺失回落中文 |
|
||||
| `force` | 可选,默认 false | 强更闸门:接口不兼容的老版本置 true |
|
||||
| `apk` | 可选,默认 `youjiala.apk` | FileServer 根下的安装包文件名 |
|
||||
|
||||
## 3. 检查与更新流程(`src/utils/appUpdate.ts`)
|
||||
|
||||
```
|
||||
checkAppUpdate(manual)
|
||||
├─ uni.request GET {当前线路}/FileServer/app-update.json(8 秒超时)
|
||||
├─ plus.runtime.getProperty 取本机 versionCode
|
||||
├─ 清单 ≤ 本机 → manual 时 toast「已是最新版本」,否则静默
|
||||
├─ 自动检查且该版本被「稍后再说」跳过过 → 静默不再弹(强更不受此限)
|
||||
├─ uni.showModal:立即更新 / 稍后再说(force 时右钮换「退出应用」,点它 plus.runtime.quit)
|
||||
├─ iOS → 只弹提示引导去网页下载(应用内装不了 apk)
|
||||
└─ Android → plus.downloader 下整包(showLoading 刷百分比)→ plus.runtime.install 拉起系统安装器
|
||||
```
|
||||
|
||||
要点:
|
||||
|
||||
- **地址口径不另起炉灶**:清单和 apk 都过 `absoluteFileUrl()`,自动跟随「访问线路」——内网直连取内网开发机的包、公网取 uat 的包(归一规则见 [file-url.md](./file-url.md))。
|
||||
- **文案住语言包**:弹窗/提示全部取 `locale/lang/*.json` 的 `AppUpdate` 段(双语维护规范);非组件上下文拿不到 `useLocale()`,`msg()` 按 `currentUiLocale()` 直接从语言包对象取词并做 `{version}` 占位替换。
|
||||
- **并发闸门**:模块级 `checking` 标志,自动/手动撞车只跑一次;`autoChecked` 保证一次冷启动只静默查一次。
|
||||
- **失败静默与提示分工**:自动检查网络失败不打扰用户;手动入口给「检查更新失败,请检查网络或访问线路后重试」。
|
||||
|
||||
## 4. 触发点
|
||||
|
||||
| 入口 | 位置 | 行为 |
|
||||
| --- | --- | --- |
|
||||
| 启动自动 | `App.vue` 的 `onLaunch` 延后 5 秒调 `autoCheckAppUpdate()` | 静默:无新版/被跳过/失败都不吭声,只有发现新版才弹 |
|
||||
| 手动 | 「我的 → 检查更新」行(仅 `APP-PLUS` 条件编译,右侧显示当前版本号) | 全量反馈:检查中 loading、已最新 toast、失败 toast,无视「稍后再说」记账 |
|
||||
|
||||
5 秒延时是为了避开隐私弹窗与启动首帧;若实测仍与隐私弹窗撞车,可改挂到登录成功后。
|
||||
|
||||
## 5. 端间差异
|
||||
|
||||
| 端 | 行为 |
|
||||
| --- | --- |
|
||||
| Android App | 完整流程:弹窗 → 下载 → `plus.runtime.install` 系统安装器 |
|
||||
| iOS App | 只弹「请前往网页版下载最新安装包」提示(签名分发限制,应用内装不了) |
|
||||
| H5 / 小程序 | 整个模块空转(`checkAppUpdate` 返回 `unsupported`),入口也不渲染 |
|
||||
|
||||
manifest 已补 `android.permission.REQUEST_INSTALL_PACKAGES`;真机首次安装仍需用户在系统里允许「安装未知应用」。
|
||||
|
||||
## 6. 强制更新语义
|
||||
|
||||
`force: true` 时:
|
||||
|
||||
- 弹窗右钮从「稍后再说」换成「退出应用」,点退出即 `plus.runtime.quit()`,没有第三条路;
|
||||
- 自动检查**不受**「稍后再说」记账限制——跳过的版本只要清单还标着 force 就继续弹。
|
||||
|
||||
一期不做「最低支持版本」独立闸门:强与否由发版时改 json 的 `force` 字段人工决定。
|
||||
|
||||
## 7. 发版流程(三步)
|
||||
|
||||
1. **版本号三处同步**(`common/constant.ts` 注释已有约定):`manifest.json`(versionName + versionCode)、`package.json`(version)、`common/constant.ts` 的 `APP_INFO.version`;
|
||||
2. HBuilderX 打新包,替换 `D:\Net8\FileServer\youjiala.apk`;
|
||||
3. 改 `D:\Net8\FileServer\app-update.json` 的 `versionCode` / `versionName` / `description`(必要时 `force`)。
|
||||
|
||||
## 8. 验证方法
|
||||
|
||||
- 当前清单 `versionCode=1` 与已装包相同 → 手动检查应提示「已是最新版本」;
|
||||
- 想看完整更新弹窗:把 json 的 `versionCode` 临时改成 `2`(拿现有 apk 也能走完下载 → 系统安装器全流程);
|
||||
- 「稍后再说」记账存在本地 key `app-update-skipped`(记被跳过的 versionCode),手动检查不受限,清缓存或换更高新版本即恢复弹窗。
|
||||
|
||||
## 9. 决策留痕与二期
|
||||
|
||||
- **为什么不走后端接口管版本(方案 C)**:要过权限/功能/组 MySQL 登记 + 自动生成链 + 后端重启,一期收益不成比例;静态 json 与 apk 本来就在 FileServer 同一目录,发布动作最轻。
|
||||
- **wgt 热更新(方案 B)留作二期**:包体大了以后再加「纯前端改动发 wgt 小包、动原生才发整包」的双通道,需要发布流程配合产 wgt 并守版本纪律。
|
||||
- 若将来引入应用商店分发或需要灰度/最低版本策略,本文口径作废重议。
|
||||
Reference in new issue
Block a user