更新记录
1.0.0(2026-08-29) 下载此版本
android app版本更新
平台兼容性
uni-app x(5.0)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| - | - | √ | - | - | - |
ff-uni-upgrade
App 版本升级 UTS 插件,封装断点续传、通知栏进度、自动重试、MD5 校验与系统安装等通用能力。
平台支持
| 平台 | 实现状态 | 升级方式 |
|---|---|---|
| Android | ✅ 已实现 | APK 整包下载(断点续传 + 自动重试 + 通知栏进度)+ 系统安装 |
| iOS | ⚠️ 已声明未实现 | 暂无实现(package.json 声明 √,源码未提供 utssdk/app-ios/) |
| HarmonyOS | ⚠️ 已声明未实现 | 暂无实现(package.json 声明 √,源码未提供 utssdk/app-harmony/) |
三端 API 表保持一致:iOS / HarmonyOS 端当前没有任何实现文件,调用本插件在非 Android 平台会因找不到
utssdk/app-ios/index.uts或utssdk/app-harmony/index.uts而编译失败。如需 iOS / HarmonyOS 支持,需自行补充对应平台的 UTS / Swift / ArkTS 实现,或将 package.json 的uni_modules.client中对应平台标记为×。
⚠️ Android 端集成说明(重要)
Android 端下载内核为 MZCretin/AutoUpdateProject(JitPack 依赖 com.github.MZCretin:AutoUpdateProject:v2.0.7,见 utssdk/app-android/config.json)。注意:
- v2.0.7 是 JitPack 上唯一同时有 AAR 且为 AndroidX 依赖的版本(已实测 v2.0.8 / v2.0.9 / v2.1.0 在 JitPack 上只有 POM 无 AAR;曾尝试的
cretinautoupdatelibrary:*内部 artifact 不存在,JitPack 直接返回 401 Unauthorized)。升级该库版本前务必先访问 https://jitpack.io/com/github/MZCretin/AutoUpdateProject// 确认 。.aar存在 - 真机运行 / 云打包必须使用自定义基座:引入三方 gradle 依赖后,标准基座不包含该依赖,需提交云端打包生成自定义基座后方可生效。
- 需要 HBuilderX 4.36+:config.json 中通过
project.repositories配置了 JitPack 仓储。 - 依赖坐标说明:该库 JitPack 上的 POM 不带任何传递依赖(v2.0.7 已实测),故 config.json 中已显式补齐
com.liulishuo.filedownloader:library:1.7.6(断点续传引擎)及 androidx 依赖,请勿删除。 - FileProvider 冲突风险:AutoUpdateProject 自带 authority 为
${applicationId}.fileprovider的 FileProvider。若宿主 App 或其他插件已声明相同 authority,云打包合并 manifest 时会失败,需二选一。
由该库提供的 Android 端能力:
- 断点续传:下载写入
.temp临时文件,中断/暂停/杀进程后再次下载自动从断点继续 - 下载失败自动重试 3 次
- 通知栏实时下载进度(失败后可点击通知栏重新下载)
- 相同版本只下载一次:传入
fileSize时,本地已有完整 APK 直接唤起安装器 - MD5 校验:传入
md5时下载完成后校验,校验失败不安装 - 下载完成后自动唤起系统安装器(Android 8+ 安装权限由本插件前置检查并引导跳转设置页)
Android 权限清单
由 utssdk/app-android/AndroidManifest.xml 自动合并到宿主 manifest:
| 权限 | 用途 |
|---|---|
android.permission.INTERNET |
下载 APK |
android.permission.ACCESS_NETWORK_STATE |
网络状态 |
android.permission.REQUEST_INSTALL_PACKAGES |
Android 8.0+ 安装未知应用 |
android.permission.POST_NOTIFICATIONS |
Android 13+ 下载进度通知栏 |
安装
将 ff-uni-upgrade 放入项目的 uni_modules/ 目录下,HBuilderX 会自动识别。
使用示例
import {
checkUpgrade, , onResult,
offProgress, offResult, dispose,
getCurrentProgress, resumeDownload
} from '@/uni_modules/ff-uni-upgrade'
// 1. 监听下载进度
((e) => {
console.log(`下载进度: ${e.percent}% (${e.downloaded}/${e.total})`)
})
// 2. 监听结果
onResult((r) => {
if (r.status === 'success') {
console.log('下载完成,安装器已自动唤起')
} else if (r.status === 'cancel') {
console.log('用户取消')
} else {
console.error('升级失败:', r.error)
}
})
// 3. 触发升级检查
checkUpgrade({
version: '1.2.0',
downloadUrl: 'https://example.com/app-v1.2.0.apk',
updateContent: '1. 修复已知问题\n2. 优化性能',
isForceUpdate: false,
versionCode: 25, // 可选:传给升级库做版本比对
fileSize: 31338250, // 可选:启用"已下载文件完整性校验"
md5: '68919BF998C29DA3F5BD2C0346281AC0' // 可选:下载完成后 MD5 校验
})
// 4. 主动查询当前进度(无需注册 )
const cur = getCurrentProgress()
if (cur != null) {
console.log(`当前进度: ${cur.percent}%`)
}
// 5. 主动恢复之前暂停的下载(URL 必须与上次一致)
const resumed = resumeDownload({
version: '1.2.0',
downloadUrl: 'https://example.com/app-v1.2.0.apk',
updateContent: '',
isForceUpdate: false
})
console.log(resumed ? '续传已触发' : '无断点可恢复')
// 6. 页面卸载时释放资源(重要!)
onUnload(() => {
dispose()
})
API
checkUpgrade(options: UpgradeOptions, platformConfig?: string): void
触发升级检查并展示弹窗。platformConfig 为三端 API 表占位(Android 端忽略;iOS / HarmonyOS 当前未实现该参数语义)。
参数 UpgradeOptions:
version: string— 新版本号(显示用,Android 端同时用作 APK 文件名)downloadUrl: string— APK 下载地址(Android 必填;传空字符串会被resultDispatcher('fail', ...)上报为参数错误)updateContent: string— 更新内容(支持\n换行)isForceUpdate: boolean— 是否强制升级(true 时弹窗的 cancelText 不展示,按返回键 / 点遮罩会再次弹出)versionCode?: number— 新版本 versionCode(可选,Android 端传给升级库做版本比对)fileSize?: number— APK 总字节数(可选,Android 端启用已下载文件完整性校验)md5?: string— APK 文件 MD5(可选,Android 端下载完成后校验,失败不安装)
onProgress(callback): void
注册下载进度回调,回调参数:
percent: number— 0-100(服务器未返回总长度时为 -1)downloaded: number— 已下载字节(未传fileSize时为 -1)total: number— 总字节(未传fileSize时为 -1)
必须用 @UTSJS.keepAlive 标注(本插件已在 Android 实现内标注)—— 跨边界回调若不持有强引用会被 JSCore GC 释放,导致"调一次后失效"。
多次注册会替换前一次。建议在页面 onUnload 中调用 offProgress() 或 dispose() 释放回调引用。
offProgress(): void
注销下载进度回调(与 onProgress 配对)。
onResult(callback): void
注册升级结果回调,回调参数:
status: 'success' | 'cancel' | 'fail'error?: string | null— 失败时的错误描述
同 onProgress,回调函数须被 UTS 顶层模块级 var 持有引用才能跨多次触发持续生效。本插件通过 resultCallback 模块级变量持有引用,无需业务方额外处理。
offResult(): void
注销升级结果回调(与 onResult 配对)。
dispose(): void
释放升级插件资源:offProgress() + offResult() + clearResumeCache(),并清空 Kotlin 端 UpgradeCallbacks 的 MD5 失败回调。
建议在页面 onUnload 或 onBeforeUnmount 中调用,避免:
- 路由切换后旧页面的回调仍被触发,错误地修改新页面的响应式状态
- 已卸载页面持有的
reactive()对象被闭包引用,无法被 GC - 用户离开页面但断点文件仍占用存储空间
cancelUpgrade(): void
暂停当前升级流程并保留断点记录(不删除 .temp 半成品文件)。
下次 checkUpgrade 相同 downloadUrl 时自动从断点继续。彻底丢弃下载进度请调用 clearResumeCache()。
取消事件由 Kotlin 端 listener.pause() 回调统一上报(通过 onResult 的 status: 'cancel'),本方法不直接 dispatch result(避免双重上报)。
getCurrentProgress(): ProgressEvent | null(v2.1.0 新增)
主动查询当前下载进度(无需注册 onProgress)。未启动下载时返回 null。
返回 ProgressEvent 字段同 onProgress 回调参数。
适用于:从其他页面返回升级页时刷新进度条;不依赖回调注册的轮询场景。
getResumeInfo(): ResumeInfo | null
查询是否存在未完成的下载(App 重启后可据此提示用户继续)。无未完成下载时返回 null。
返回 ResumeInfo:
url: string— 上次未完成下载的地址fileName: string— APK 文件名downloaded: number— 已下载字节(以.temp文件实际大小为准)total: number— 总字节(未知时为 -1)percent: number— 进度百分比 0-100(未知时为 -1)
v2.1.0 的 Kotlin 层 JSON 中新增了
hasResume: boolean字段用于内部判断;UTS 端ResumeInfo类型未导出该字段,调用方判断"是否有断点"直接!= null即可。
resumeDownload(options: UpgradeOptions): boolean(v2.1.0 新增)
主动恢复之前暂停的下载。URL 必须与上次一致才能续传,否则返回 false。
成功触发后返回 true。
clearResumeCache(): void
清除断点续传缓存:删除 .temp 半成品文件、已下载 APK 与任务记录(Kotlin 端用 AppUpdateUtils.clearAllData() + FileDownloadUtils.deleteTargetFile / deleteTempFile 兜底,库清理失败时也能彻底删除)。
installDownloaded(): void
安装已下载的 APK(Android 端)。正常流程下下载完成后升级库会自动唤起系统安装器,本方法用于安装被取消或"安装未知应用"权限授权后重试的场景。Android 8+ 未授予权限时会跳转系统设置页。
v2.1.0 强化:进程被杀后 currentFilePath 内存值丢失,本方法会自动从以下 3 级回退重建路径:
- 内存
currentFilePath(运行时缓存) - SharedPreferences
KEY_FILE_PATH(downloadComplete()时commit()原子化写入) AppUtils.getAppLocalPath(versionName)(按 versionName 重新计算路径;若找到会同步写回 SharedPreferences)
保证"下载完成后被杀进程"也能继续安装。
Android 下载实现说明
Android 端基于 AutoUpdateProject(见 utssdk/app-android/UpgradeNative.kt 的薄封装):
- 下载引擎为库内置的 filedownloader:断点续传(
.temp文件 + Range 请求)、失败自动重试 3 次 - 下载进度实时显示在通知栏(Android 13+ 需通知权限,失败后可点击通知栏重新下载)
- APK 存储路径为应用专属缓存目录
Android/data/<pkg>/cache/<pkg>/apks/<应用名>_<版本号>.apk - 下载完成后自动唤起系统安装器;传入
md5时先校验 MD5,校验失败不安装 - Android 8+ 的"安装未知应用"权限在下载开始前前置检查并引导跳转设置页(库内安装逻辑未做此检查,由本插件补齐;
installDownloaded()内同样检查) - 暂停 / 出错 / 杀进程均保留断点,App 重启后
getResumeInfo()可感知,再次触发升级自动续传
v2.1.0 重构:
- UTS 端删除
setInterval轮询:Kotlin 端AppDownloadListener通过模块级分发器(progressDispatcher / resultDispatcher / md5FailDispatcher)直接回调到 UTS。分发器由 UTS 模块级var持有引用避免被 GC;onProgress / onResult函数用@UTSJS.keepAlive标注保护 callback 参数。 - 回调在主线程上派发(
Handler(Looper.getMainLooper()).post),避免子线程修改 UTS 响应式状态时静默失败。 - 状态机单一来源:Kotlin 端用
UpgradeStatusenum(Idle / Downloading / Paused / Completed / Error)替代 5 个STATUS_xxx常量,UTS 端不再做状态判定。 - 错误码集中:Kotlin 端用
UpgradeErrorCodeenum 维护(NETWORK=1001 / DOWNLOAD=1002 / INSTALL=1003 / PARAMS=1004 / NOT_SUPPORTED=1005 / CANCEL=1006 / PERMISSION_DENIED=1007);UTS 端通过UPGRADE_ERR_xxx常量导出公共契约。 SharedPreferences任务边界写入用commit()而非apply()(URL / versionName / fileSize 三个字段原子化)。installDownloaded自愈:3 级回退(内存 → SharedPreferences →AppUtils.getAppLocalPath)。- 取消上报单一来源:
cancelUpgrade()仅调UpgradeNative.pauseDownload(),由 Kotlin 端listener.pause()通过onResult的status: 'cancel'统一上报(v2.0.0 的双源上报已修复)。
错误码
错误码在 Kotlin 端集中在 UpgradeErrorCode enum 中维护,UTS 端通过 UPGRADE_ERR_xxx 常量导出公共契约(utssdk/interface.uts):
| 错误码 | 常量名 | 含义 | 触发场景 |
|---|---|---|---|
| 1001 | UPGRADE_ERR_NETWORK |
网络异常 | 网络不通 / DNS 解析失败 / 下载过程断网 |
| 1002 | UPGRADE_ERR_DOWNLOAD |
下载失败 | 库内 filedownloader 重试 3 次后仍失败;MD5 校验不通过 |
| 1003 | UPGRADE_ERR_INSTALL |
安装失败 | installApk 抛异常 / 系统安装器返回错误 |
| 1004 | UPGRADE_ERR_PARAMS |
参数错误 | downloadUrl 为空 / version 为空 / UpgradeOptions 为 null |
| 1005 | UPGRADE_ERR_NOT_SUPPORTED |
当前平台不支持 | iOS / HarmonyOS 端调用(本插件未实现时) |
| 1006 | UPGRADE_ERR_CANCEL |
取消升级 | 用户主动 cancelUpgrade()(v2.0.0 起通过 onResult status: 'cancel' 上报,不走此错误码;保留以便业务方按需消费) |
| 1007 | UPGRADE_ERR_PERMISSION_DENIED |
权限被拒 | Android 8+ 未授予"安装未知应用"权限 / 权限检查后用户未授权 |
v2.1.0 起
onResult回调的status字段已覆盖全部成功 / 取消 / 失败场景;UpgradeError类(utssdk/unierror.uts)保留供业务方按错误码二次封装。
注意事项
- 仅 Android 端实现:iOS / HarmonyOS 端当前未提供实现源码,在对应平台调用本插件会编译失败
- 自定义基座:Android 端引入了 JitPack 三方依赖,真机运行与云打包需使用自定义基座
- 安装未知应用权限:Android 8.0+ 首次升级会引导用户开启"安装未知应用"权限;用户在设置页授权后需重新触发升级
- 通知权限:Android 13+ 需授予通知权限才能看到下载进度通知栏(权限已在插件 manifest 中声明,但需业务方在 App 启动时主动申请)
- 回调清理:务必在
onUnload / onBeforeUnmount中调用dispose(),避免已卸载页面的回调继续触发 - 跨页面共享回调:本插件的模块级变量持有回调引用,所有页面共享同一回调实例。若需要按页面隔离回调,可在使用前
offProgress / offResult后再onProgress / onResult
调试与日志
Kotlin 端统一使用 TAG ff-uni-upgrade 输出日志。关键日志点:
ensureInit: applicationContext is not Application— 初始化失败,应用上下文不是ApplicationensureNativeBridge: ...— 桥接AppDownloadListener/MD5CheckListener到库startDownload: url=..., version=..., fileSize=..., md5Check=...— 任务启动clearResumeCache: done— 断点缓存清除完成persistFilePath: .../installDownloaded: ...— 进程被杀后自愈路径
UTS 端关键日志:
[ff-uni-upgrade] MD5 校验失败:期望 xxx,实际 yyy— MD5 不匹配[ff-uni-upgrade] showModal fail: ...— 升级弹窗显示失败
版本
- 2.1.0(2026-08-28)— Android 端重构:删除 UTS setInterval 轮询,改用 Kotlin→UTS 直接回调(typealias + 单例属性 + 主线程分发 + @UTSJS.keepAlive);
installDownloaded在currentFilePath丢失(进程被杀)后从 SharedPreferences 自愈;SharedPreferences任务边界写入commit()原子化;状态机单一来源(UpgradeStatusenum);错误码集中(UpgradeErrorCodeenum);新增offProgress / offResult / dispose / getCurrentProgress / resumeDownloadAPI;错误码新增 1007 PERMISSION_DENIED。依赖维持AutoUpdateProject:v2.0.7(v2.0.8+ 在 JitPack 上无 AAR,cretinautoupdatelibrary:*内部 artifact 不存在,已实测 JitPack 401 Unauthorized) - 2.0.0(2026-08-28)— Android 端重构为集成 AutoUpdateProject(filedownloader 断点续传 + 自动重试 + 通知栏进度 + MD5 校验),
UpgradeOptions新增可选字段versionCode/fileSize/md5 - 1.1.0(2026-08-27)— 自实现 Range/If-Range 断点续传,新增
getResumeInfo / clearResumeCacheAPI - 1.0.0(2026-08-27)— 初始版本,仅支持 Android 端

收藏人数:
下载插件并导入HBuilderX
赞赏(0)
下载 89
赞赏 1
下载 12540767
赞赏 1947
赞赏
京公网安备:11010802035340号