背景
目前 App 的检查更新能力仍然是 Android Early 专用链路:
AppUpdateService.isSupported 只支持 Android && Early channel。
- 设置页里的更新入口只在
Platform.isAndroid && AppFlavor.isEarly 时展示。
- 启动自动检查仍走
_scheduleEarlyUpdateCheck()。
- 版本来源已经具备基础能力:
package_info_plus 可以读取 versionName/buildNumber,AppFlavor 已经区分 global/cn/globalEarly/cnEarly/globalDev/cnDev。
我们现在要把检查更新升级为全渠道统一能力,覆盖:
- iOS 国区 App Store
- iOS 外区 App Store
- Android 国区应用商店
- Google Play / 海外 Android 商店
- GitHub / 官网直装 APK
- Early / Dev 包
用户侧也需要一个统一的 关于 Memex / About 页面,用来展示 App logo、当前版本、渠道、安装来源、检查更新入口和复制诊断信息。
方案结论
采用 官方站静态 Manifest 作为 canonical 策略源,GitHub Releases 作为 APK 资产源与镜像/fallback。
推荐主地址:
https://www.memexlab.ai/updates/v1/manifest.json
https://www.memexlab.ai/updates/v1/manifest.sha256
对应放在 memex_home:
public/updates/v1/manifest.json
public/updates/v1/manifest.sha256
注意:不要使用 /v1/... 路径,因为 memex_home 当前会把 /v1/:path* rewrite 到外部 gateway。
GitHub Releases 继续负责:
- Early/Dev/direct APK release asset
- release notes
- manifest 镜像/fallback
- 人工审计和回溯
App 客户端不应把 GitHub API 作为全渠道主策略入口,避免国内网络、API rate limit、无认证 token 等问题。
改造范围
1. memex App
新增/重构:
2. memex_home
- 新增静态 manifest 路径:
public/updates/v1/manifest.json。
- 新增 manifest hash 文件:
public/updates/v1/manifest.sha256。
- 新增 schema 文档或校验脚本,避免手工改坏。
- 明确缓存策略:manifest 需要短缓存,APK/图片等资产可以长缓存。
- 后续可把
/updates/* 接到 CDN/OSS,但 first pass 不需要后端。
3. 发布流程 / CI
- 打包时生成:
versionName
buildNumber
flavor/channel
- APK
sha256
- APK
sizeBytes
- 发布时更新 manifest 并校验 schema。
- GitHub Release 上传 APK 和可选 manifest mirror。
- 失败时阻断发布,避免客户端读取半成品 manifest。
Manifest 建议结构
{
"schemaVersion": 1,
"generatedAt": "2026-06-16T00:00:00Z",
"channels": {
"ios_cn_stable": {
"provider": "app_store",
"bundleId": "com.memexlab.memex.cn",
"country": "cn",
"latestBuild": 118,
"minSupportedBuild": 117,
"storeUrl": "https://apps.apple.com/cn/app/..."
},
"android_cn_stable": {
"provider": "android_store",
"packageName": "com.memexlab.memex.cn",
"latestBuild": 118,
"minSupportedBuild": 117,
"fallbackStoreUrl": "market://details?id=com.memexlab.memex.cn"
},
"android_global_early": {
"provider": "github_apk",
"packageName": "com.memexlab.memex.early",
"latestBuild": 118,
"minSupportedBuild": 117,
"versionName": "1.0.35",
"apkUrl": "https://github.com/memex-lab/memex/releases/download/.../memex_globalEarly_1.0.35_118.apk",
"sha256": "...",
"sizeBytes": 123456789,
"releaseNotesUrl": "https://github.com/memex-lab/memex/releases/tag/..."
}
}
}
重点风险盘点
1. Manifest 可用性风险
风险:官方站不可达、CDN 异常、DNS 污染、客户端网络失败,导致检查更新不可用。
规避:
- App 内置 fallback manifest。
- 官方站失败后尝试 GitHub mirror。
- 所有失败都降级为“无法检查更新”,不能阻塞 App 主流程。
- About 页仍显示本地版本信息。
2. Manifest 缓存/回滚风险
风险:CDN 缓存过久导致错误 manifest 无法快速修正;或者用户拿到半旧半新的更新策略。
规避:
- manifest 使用短缓存。
- APK 使用带版本号的不可变 URL。
- manifest schema 增加
generatedAt 和可选 expiresAt。
- 发布流程必须支持回滚到上一份 manifest。
3. Manifest 被篡改风险
风险:攻击者篡改 manifest,把 direct APK 指向恶意包。
规避:
- 只走 HTTPS。
- APK 下载必须校验
sha256 和 size。
- direct APK 安装前校验文件扩展名、大小、hash。
- 后续升级为 manifest 签名校验(如 Ed25519 公钥内置客户端)。
- GitHub/direct APK 不允许更新商店签名包。
4. APK 签名/渠道互刷风险
风险:GitHub APK 试图覆盖 App Store/Google Play/国内商店安装包,因签名不一致失败;更糟糕的是用户被引导到错误渠道。
规避:
- manifest 中明确
packageName、channel、distribution。
- provider 选择必须校验当前包名和 flavor。
- 商店来源安装包只跳商店,不走 APK 下载。
- GitHub/direct/Early 只更新同签名 direct/Early 包。
5. 安装来源识别不准
风险:Android installer source 在某些 ROM、迁移安装、备份恢复后为空或不可靠,导致跳错商店。
规避:
- installer source 只作为 hint,不作为唯一事实。
- 优先使用 packageName/flavor/channel。
- manifest 提供 fallbackStoreUrl。
- About 页展示安装来源,便于用户反馈。
6. 版本比较错误
风险:versionName 带 suffix(Early/Dev/日期/hash)时字符串比较出错。
规避:
- 新旧判断统一使用整数
buildNumber。
versionName 只用于展示。
- manifest schema 强制
latestBuild/minSupportedBuild 为整数。
- 单测覆盖 stable/early/dev/cn/global 的版本比较。
7. 强制更新体验风险
风险:误设 minSupportedBuild 导致用户被错误拦截;离线用户无法进入 App。
规避:
minSupportedBuild 默认不启用硬拦截。
- 强制更新必须有二次确认/发布 checklist。
- 本地优先 App 不应因为检查更新失败阻断核心使用。
- 仅对明确不可兼容版本做强拦截。
8. 启动自动检查打扰风险
风险:启动弹窗频繁、影响记录入口、降低首屏体验。
规避:
- 保留最小检查间隔(如 12 小时)。
- Stable 只弱提示,不自动弹强对话框。
- Early/direct 可提示下载,但仍需用户确认安装。
- Dev 默认关闭自动检查。
9. 国内网络和 GitHub 依赖风险
风险:CN 用户访问 GitHub 慢或失败,导致更新体验差。
规避:
- CN 渠道默认使用官方站/国内 CDN manifest。
- APK 如需 direct 下载,优先国内对象存储/CDN。
- GitHub 只作为 mirror/fallback,不是 CN 主路径。
10. Store policy 风险
风险:iOS 或应用商店不允许 App 内自行下载安装更新包。
规避:
- iOS 只检查和跳 App Store,不下载 IPA。
- 商店安装的 Android 稳定包只跳对应商店。
- APK 下载/系统安装器仅用于 GitHub/direct/Early 包。
11. 并发和缓存清理风险
风险:用户重复点击下载、清缓存与下载冲突、半包被复用、安装并发。
规避:
- 保留现有
AppUpdateService 的 service 层并发 ownership。
- 下载使用
.part 临时文件。
- hash/size 校验失败删除临时文件。
- 单测覆盖并发下载、下载中清理、缺失 APK 安装拒绝。
12. UI 信息暴露/诊断风险
风险:About 页复制诊断信息时暴露不该有的用户数据。
规避:
- 诊断信息只包含 app/build/channel/package/installer/source/manifest timestamp。
- 不包含 userId、路径、LLM key、日志内容。
验收标准
备选方案
A. 只使用 GitHub Releases / GitHub manifest
优点:最省事,发布链路简单。
缺点:客户端依赖 GitHub 网络和 API/rate limit;CN 体验差;品牌和策略入口不稳定。
结论:不推荐作为 canonical,只适合 mirror/fallback。
B. 官方站静态 manifest + GitHub fallback
优点:不需要新后端;官方域名可控;适合 CN/global 分流;GitHub 保留透明和灾备。
缺点:需要维护静态文件和发布校验。
结论:推荐一期采用。
C. 独立后端 Update API
优点:可做动态灰度、统计、分群、签名下发。
缺点:引入服务端运维、鉴权、可用性、更多故障面。
结论:当前过重,等静态 manifest 不够用再升级。
实施建议
一期直接做完整架构,但控制商店深集成范围:
- 先实现官方站静态 manifest、AppInfo、About 页、provider router。
- 商店渠道 first pass 先做检查和跳转。
- GitHub/direct/Early 保留 APK 下载和安装能力,并补 hash 校验。
- Google Play Core、华为 AppGallery SDK 等深集成后续按真实上架渠道分 issue 推进。
背景
目前 App 的检查更新能力仍然是 Android Early 专用链路:
AppUpdateService.isSupported只支持Android && Early channel。Platform.isAndroid && AppFlavor.isEarly时展示。_scheduleEarlyUpdateCheck()。package_info_plus可以读取versionName/buildNumber,AppFlavor已经区分global/cn/globalEarly/cnEarly/globalDev/cnDev。我们现在要把检查更新升级为全渠道统一能力,覆盖:
用户侧也需要一个统一的
关于 Memex / About页面,用来展示 App logo、当前版本、渠道、安装来源、检查更新入口和复制诊断信息。方案结论
采用 官方站静态 Manifest 作为 canonical 策略源,GitHub Releases 作为 APK 资产源与镜像/fallback。
推荐主地址:
对应放在
memex_home:注意:不要使用
/v1/...路径,因为memex_home当前会把/v1/:path*rewrite 到外部 gateway。GitHub Releases 继续负责:
App 客户端不应把 GitHub API 作为全渠道主策略入口,避免国内网络、API rate limit、无认证 token 等问题。
改造范围
1.
memexApp新增/重构:
AppInfoServiceappName/packageName/versionName/buildNumber。AppFlavor.name/channel/region。UpdateManifestServicemanifest.sha256;后续可升级为签名校验。AppUpdateRouter/ provider 架构AppBuildInfo + manifest + installerSource选择 provider。Providers
AppleAppStoreUpdateProviderAndroidStoreRedirectProviderGooglePlayUpdateProvider(可先跳转 Play Store,深度 Play Core 后续补)GithubApkUpdateProvider(复用现有 APK 下载/安装能力)NoopUpdateProviderAbout 页
关于 Memex入口。启动自动检查
_scheduleEarlyUpdateCheck()泛化为_scheduleAppUpdateCheck()。2.
memex_homepublic/updates/v1/manifest.json。public/updates/v1/manifest.sha256。/updates/*接到 CDN/OSS,但 first pass 不需要后端。3. 发布流程 / CI
versionNamebuildNumberflavor/channelsha256sizeBytesManifest 建议结构
{ "schemaVersion": 1, "generatedAt": "2026-06-16T00:00:00Z", "channels": { "ios_cn_stable": { "provider": "app_store", "bundleId": "com.memexlab.memex.cn", "country": "cn", "latestBuild": 118, "minSupportedBuild": 117, "storeUrl": "https://apps.apple.com/cn/app/..." }, "android_cn_stable": { "provider": "android_store", "packageName": "com.memexlab.memex.cn", "latestBuild": 118, "minSupportedBuild": 117, "fallbackStoreUrl": "market://details?id=com.memexlab.memex.cn" }, "android_global_early": { "provider": "github_apk", "packageName": "com.memexlab.memex.early", "latestBuild": 118, "minSupportedBuild": 117, "versionName": "1.0.35", "apkUrl": "https://github.com/memex-lab/memex/releases/download/.../memex_globalEarly_1.0.35_118.apk", "sha256": "...", "sizeBytes": 123456789, "releaseNotesUrl": "https://github.com/memex-lab/memex/releases/tag/..." } } }重点风险盘点
1. Manifest 可用性风险
风险:官方站不可达、CDN 异常、DNS 污染、客户端网络失败,导致检查更新不可用。
规避:
2. Manifest 缓存/回滚风险
风险:CDN 缓存过久导致错误 manifest 无法快速修正;或者用户拿到半旧半新的更新策略。
规避:
generatedAt和可选expiresAt。3. Manifest 被篡改风险
风险:攻击者篡改 manifest,把 direct APK 指向恶意包。
规避:
sha256和 size。4. APK 签名/渠道互刷风险
风险:GitHub APK 试图覆盖 App Store/Google Play/国内商店安装包,因签名不一致失败;更糟糕的是用户被引导到错误渠道。
规避:
packageName、channel、distribution。5. 安装来源识别不准
风险:Android installer source 在某些 ROM、迁移安装、备份恢复后为空或不可靠,导致跳错商店。
规避:
6. 版本比较错误
风险:
versionName带 suffix(Early/Dev/日期/hash)时字符串比较出错。规避:
buildNumber。versionName只用于展示。latestBuild/minSupportedBuild为整数。7. 强制更新体验风险
风险:误设
minSupportedBuild导致用户被错误拦截;离线用户无法进入 App。规避:
minSupportedBuild默认不启用硬拦截。8. 启动自动检查打扰风险
风险:启动弹窗频繁、影响记录入口、降低首屏体验。
规避:
9. 国内网络和 GitHub 依赖风险
风险:CN 用户访问 GitHub 慢或失败,导致更新体验差。
规避:
10. Store policy 风险
风险:iOS 或应用商店不允许 App 内自行下载安装更新包。
规避:
11. 并发和缓存清理风险
风险:用户重复点击下载、清缓存与下载冲突、半包被复用、安装并发。
规避:
AppUpdateService的 service 层并发 ownership。.part临时文件。12. UI 信息暴露/诊断风险
风险:About 页复制诊断信息时暴露不该有的用户数据。
规避:
验收标准
sha256和 size。备选方案
A. 只使用 GitHub Releases / GitHub manifest
优点:最省事,发布链路简单。
缺点:客户端依赖 GitHub 网络和 API/rate limit;CN 体验差;品牌和策略入口不稳定。
结论:不推荐作为 canonical,只适合 mirror/fallback。
B. 官方站静态 manifest + GitHub fallback
优点:不需要新后端;官方域名可控;适合 CN/global 分流;GitHub 保留透明和灾备。
缺点:需要维护静态文件和发布校验。
结论:推荐一期采用。
C. 独立后端 Update API
优点:可做动态灰度、统计、分群、签名下发。
缺点:引入服务端运维、鉴权、可用性、更多故障面。
结论:当前过重,等静态 manifest 不够用再升级。
实施建议
一期直接做完整架构,但控制商店深集成范围: