面向非 Google Play 分发 Android 应用的轻量、安全自更新模块。
简体中文 | English
Note
Novi 由 AlfWorks 开发。此 GitHub 仓库是其权威 GitLab 仓库的公开镜像。
Novi is developed under AlfWorks. This GitHub repository is a public mirror of the canonical GitLab repository.
Important
Novi 0.1.1 已发布到 Maven Central。
Novi 负责从验证已签名的发布清单开始,完成版本检查、APK 下载与验证,并将安装交给 Android 系统安装器。宿主应用始终负责决定检查时机、管理界面,并取得用户明确同意。
Core 仅依赖 Android 平台与 Kotlin 标准库。独立的 Compose 模块提供可选的 Material 3 状态驱动对话框;仓库还附带一个零第三方依赖的 Windows 更新源托管程序。
- 对发布清单原始字节进行 P-256 分离签名验证。
- 有优先级的多更新源,支持故障转移、镜像或不同发布轨道。
- 流式下载 APK,同时强制校验文件大小与 SHA-256。
- 验证应用包名、版本号与 APK 签名证书。
- 集成 Android
PackageInstaller,支持进程被替换后的安装状态恢复。 - 无安装应用权限时,安全回退到手动浏览器下载。
- 可选 Material 3 更新对话框,内置简体中文与英文资源。
- 支持自定义网络传输层,可接入代理、证书固定或宿主网络栈。
- 可使用 GitLab、对象存储、普通 Web 服务器或附带的 Windows 托管程序。
Novi 不提供静默安装、后台界面、发布私钥管理、差分更新或应用生命周期框架。
| 模块 | 用途 |
|---|---|
novi-core |
清单验证、更新检查、下载、APK 验证与安装。 |
novi-compose |
可选的状态驱动 Material 3 更新对话框。 |
sample |
用于设备与界面验证的集成示例。 |
windows-host |
兼容 Windows 的只读更新源与原子发布工具。 |
consumer-test |
以外部使用者身份验证暂存 Maven 制品的独立工程。 |
latest.json + 分离签名
|
v
使用受信任 P-256 公钥验证
|
v
比较 versionCode
|
v
从选定更新源下载 APK ------> 按顺序尝试其他更新源
|
v
大小 + SHA-256 + 包名 + 版本 + 签名者验证
|
v
Android PackageInstaller ----> 系统安装确认
|
+--------------------> 无安装权限时手动浏览器下载
每个更新源都是一个静态目录:
latest.json
latest.json.sig
artifacts/<version>/app.apk
从 Maven Central 添加 Novi(novi-compose 可选):
implementation("com.alphynia.novi:novi-core:0.1.1")
implementation("com.alphynia.novi:novi-compose:0.1.1") // 可选在 Application 作用域创建一个 Novi 实例:
val novi = Novi(
NoviConfig(
context = applicationContext,
applicationId = BuildConfig.APPLICATION_ID,
currentVersionCode = BuildConfig.VERSION_CODE.toLong(),
sources = listOf(
HttpUpdateSource(
id = "primary",
rootUrl = URL("https://updates.example.com/my-app/stable/"),
),
HttpUpdateSource(
id = "fallback",
rootUrl = URL("https://gitlab.example.com/my-app/updates/"),
),
),
manifestKeys = mapOf(
"manifest-2026" to NoviKeys.p256PublicKey(
BuildConfig.NOVI_MANIFEST_PUBLIC_KEY,
),
),
allowedApkSigners = setOf(BuildConfig.NOVI_APK_SIGNER_SHA256),
),
)从 Application 级协调器调用 checkOncePerProcess。检测到新版本后,等 Activity 进入前台,再依次执行 download -> verify -> install。Novi 不会自行启动界面。
如果应用不能请求安装软件包,Novi 会返回 ManualInstallRequired。宿主应向用户解释手动流程,并只在用户选择继续后打开其中经过签名约束的制品地址。Novi 不会请求用户授予安装权限,也不会在权限变化后自动重试安装。
Novi 按配置顺序检查更新源,并采用遇到的第一份签名有效清单。这是有意设计:优先源可以提供内测、地区、企业或其他特殊版本轨道,后续源则作为稳定版本或故障回退。
APK 首先从提供所选清单的更新源下载。如果下载失败,Novi 会使用完全相同的已签名相对路径依次尝试其他更新源。无论文件来自哪里,都必须通过应用本地信任的清单公钥和 APK 签名者策略。
除本机回环开发源外,Novi 强制使用 HTTPS。它不会跟随跨源重定向,也不会削弱 TLS 主机名验证。
生成 P-256 清单密钥,并将私钥保存在仓库之外:
openssl ecparam -name prime256v1 -genkey -noout -out manifest-private.pem
openssl ec -in manifest-private.pem -pubout -out manifest-public.pem为发布 APK 生成并签署清单:
python scripts/prepare_release.py \
--apk app-release.apk \
--application-id com.example.app \
--version-code 42 \
--version-name 1.4.0 \
--artifact-path artifacts/42/app-release.apk \
--key-id manifest-2026 \
--private-key manifest-private.pem \
--output release发布顺序必须是不可变 APK、latest.json.sig,最后才是 latest.json。附带的 Windows 发布工具会以原子操作保证这个顺序。
可选托管程序仅使用 Python 标准库,并提供与 GitLab 或其他静态 HTTPS 源相同的 Novi 协议。它支持 GET、HEAD、Range 断点下载、安全缓存头、路径限制和健康检查。
.\windows-host\run.ps1 `
-Root D:\NoviSources `
-ListenAddress 127.0.0.1 `
-Port 8080发布一个应用的更新:
python .\windows-host\publish_source.py `
--release .\release `
--apk .\app-release.apk `
--root D:\NoviSources\my-app应通过 IIS、Caddy 或 nginx 等反向代理提供 HTTPS。HTTP 托管进程只需读取权限,发布操作应使用单独的写入身份。运维细节参阅 Windows 托管文档。
Novi 使用两个彼此独立的信任层:
- 清单密钥验证发布元数据与预期制品哈希。
- APK 签名证书验证可执行应用代码。
APK 签名者白名单内置于宿主应用,远程元数据无法扩大其范围。安装前,Novi 会验证 APK 大小、SHA-256、应用 ID、版本号、签名证书,以及写入安装会话的准确字节。
部署前请阅读完整的安全模型。请勿在公开 Issue 中提交私钥、生产清单或敏感应用数据。
环境要求:
- JDK 17
- Android SDK 36
- 仓库内附带的 Gradle Wrapper
- 发布工具需要 Python 3.10+ 与 OpenSSL
运行主要检查:
./gradlew :novi-core:testDebugUnitTest \
:novi-core:lintRelease \
:novi-compose:lintRelease \
:sample:assembleDebug
python3 scripts/test_prepare_release.py
python3 scripts/test_windows_host.py
python3 scripts/test_windows_publish.py在不向外部仓库发布的情况下生成 Maven 兼容暂存制品:
./gradlew \
:novi-core:publishMavenPublicationToStagingRepository \
:novi-compose:publishMavenPublicationToStagingRepositoryCI 还会让 consumer-test 通过这些暂存 Maven 坐标构建,以发现发布元数据与传递依赖错误。
文档按职责分区,索引参见 docs/README.md。能力的权威清单是能力矩阵。
- 文档总览
- 项目概览 · 原则与边界 · 当前状态
- 能力矩阵 · 限制
- 更新流程 · 验证模型 · 模块
- 集成 · API · Compose UI
- 更新协议 · 更新源 · Windows 托管 · 发布
- 安全模型 · 威胁模型
- 设备端到端验证
- 设计决策
- 变更日志
- English README
V1 成型期间,欢迎提交问题报告和范围明确的合并请求。行为变更应说明受影响的信任边界、失败模式和兼容性影响。请保持 Core 轻量;只有收益明显高于长期成本时,才应增加新的运行时依赖。
提交改动前,请运行相关单元测试、Lint、发布工具测试与外部 Maven 消费构建。
Novi 使用 Apache License 2.0 开源。归属信息参阅 NOTICE。