uni-app app端需用uni.setstoragesync持久化小数据、文件存沙箱路径并记录路径,加防抖;unicloud同步须加版本校验防覆盖,失败入队重试;同步时机选onunload/onhide/定时器,真机需适配厂商后台限制。

uni-app App端怎么触发本地自动备份
App端没法靠浏览器的同步机制,得自己写逻辑把关键数据定期存到本地持久化区域。uni.setStorageSync 是最直接的落盘方式,但别一上来就全量 dump——容易卡主线程、覆盖出错、或被系统清理掉缓存目录。
常见错误现象:uni.getStorage 读不到上次存的数据,或者 App 杀后台后丢失;其实是用了 uni.setStorage(异步+临时存储),不是 uni.setStorageSync;或者路径写错,比如存到了 uni.getFileSystemManager().writeFile 的沙箱路径里,没走 uni 封装的 storage。
- 只对小体积结构化数据用
uni.setStorageSync,比如用户设置、表单草稿、最后操作时间戳 - 大文件(图片、录音)别硬塞进 storage,改用
uni.getFileSystemManager().saveFile存到uni.env.USER_DATA_PATH下,并记录路径到 storage - 自动备份建议加防抖:连续修改 3 秒内只存最后一次,避免高频写入拖慢 UI
- Android 上注意权限,
WRITE_EXTERNAL_STORAGE在 targetSdkVersion ≥ 30 后基本失效,必须用uni.getFileSystemManager()的沙箱路径
uniCloud 云端同步怎么避免冲突和重复上传
直接调 uniCloud.callFunction 把本地数据推上去,看似简单,实际最容易爆的是「多端编辑同一份数据」导致的覆盖问题。uniCloud 没内置乐观锁,得自己加版本字段或时间戳做校验。
使用场景:用户在手机 A 编辑了待办,还没同步,又在手机 B 改了同一项——B 先上传成功,A 后传就该被拒绝,而不是静默覆盖。
- 每次本地更新时生成或递增
version字段,上传前和服务端比对;不一致就先拉最新版再合并,或提示用户手动处理 - 服务端用
db.collection('xxx').where({ _id }).update时加条件:{ version: $lt: clientVersion },失败则返回当前最新version和内容 - 别用
db.collection('xxx').add做“同步”,那是新增,不是更新;要用doc.update或带_id的set - 网络不稳定时,上传失败的数据要进本地队列(用另一个 storage key 存 pending list),等下次冷启动或网络恢复后重试
uni-app 怎么判断该不该同步、什么时候同步
不能一有改动就立刻联网同步——耗电、费流量、还可能失败。得结合状态机来控制:只在确定在线 + 非前台低功耗状态 + 数据有变更时才触发。
性能影响:频繁调 uni.getNetworkType 或监听 uni.onNetworkStatusChange 本身不重,但若每次回调都立刻发起云函数调用,就会积压请求、触发 uniCloud 频控(默认 100 次/分钟)。
- 用
uni.getNetworkType初始化时查一次,之后只监听uni.onNetworkStatusChange做状态切换,不立即同步 - 真正上传动作放在用户主动退出页面(
onUnload)、App 进入后台(uni.onHide)、或定时器(如每 5 分钟检查一次 dirty flag) - 加个内存标记
isDataDirty = true,所有修改数据的地方都设它;同步成功后再置false,避免重复上传 - iOS 后台运行时间极短(通常几秒),
uni.onHide里不适合做完整上传,只适合触发唤醒并交由 uniCloud 的 push 或 background fetch 处理(需原生插件支持)
Android/iOS 真机上备份失败的典型原因
模拟器跑通不等于真机能用。Android 11+ 和 iOS 14+ 对文件系统和后台行为限制极严,很多本地备份逻辑在真机上直接静默失败。
错误信息常看不到,因为没 catch 到 promise 拒绝或回调错误。比如 uni.setStorageSync 在 Android 12 上某些厂商 ROM 会因沙箱策略抛异常,但不打印;iOS 上写 DOCUMENTS 目录可能被拒,只能写 Library/Caches。
- 所有 storage 和 file 操作必须包 try/catch,并打 log 到
uni.reportCustomError,否则根本不知道哪步挂了 - Android 真机务必检查 manifest 里是否声明了
android:requestLegacyExternalStorage="true"(仅兼容旧版),新项目应彻底放弃EXTERNAL_STORAGE,只用uni.env.USER_DATA_PATH - iOS 打包时确认
Info.plist里开了UIBackgroundModes(如需要后台上传),否则uni.onHide后几秒进程就被杀 - 测试阶段用
adb logcat | grep uni或 Xcode 控制台抓原生层报错,比前端 console 更准
最麻烦的不是写代码,是不同 Android 厂商对后台限制的策略不统一——有的允许 10 秒,有的 3 秒就 kill,得留足降级余地:本地存住,等下次打开再传。











