发布时间:2026/7/31 17:57:49
ArkTS 进阶之道(28):PersistentStorage 持久化状态边界——为啥应用重启后状态仍存在跨启动状态根因 ArkTS 进阶之道28PersistentStorage 持久化状态边界——为啥应用重启后状态仍存在跨启动状态根因本文是「ArkTS 进阶之道」系列第 28 篇续「ArkUI 状态联动」深水区。上篇讲状态管理装饰器全景边界V1/V2 双轨根因。本文讲持久化状态边界PersistentStorage 持久化 AppStorage 键到磁盘——根因在应用重启后状态仍存在跨启动状态。能力系列篇 28 讲过 PersistentStorage 怎么用本文讲为哈 PersistentStorage 持久化状态合法 AppStorage 应用级状态页面卸载状态仍存在不跨启动——根因在持久化状态存储槽。一、开篇PersistentStorage 不是应用级 AppStorage是持久化到磁盘的跨启动状态你写 React 时持久化状态是「localStorage 魔法」localStorage JSON 序列化到磁盘// React 持久化状态localStorage 魔法JSON 序列化到磁盘 function usePersistedState(key: string, defaultValue: any) { const [value, setValue] useState(() { const stored localStorage.getItem(key) // 从磁盘读 return stored ? JSON.parse(stored) : defaultValue }) useEffect(() { localStorage.setItem(key, JSON.stringify(value)) }, [key, value]) // 改写磁盘 return [value, setValue] } // React 持久化状态localStorage 魔法JSON 序列化到磁盘应用重启仍存在你写鸿蒙 ArkTS 时PersistentStorage持久化 AppStorage 键到磁盘——应用重启后状态仍存在// ArkTS PersistentStorage 持久化 AppStorage 键到磁盘 AppStorage.setOrCreate(persistCount, 0) PersistentStorage.persistProp(persistCount, 0) // ✅ 持久化 AppStorage 键到磁盘 Entry Component struct Index { StorageLink(persistCount) persistCount: number 0 // ✅ StorageLink 双向绑定持久化键 build() { Button(persistCount${this.persistCount}) .onClick(() { this.persistCount }) // ✅ 改 → AppStorage 同步 → PersistentStorage 持久化到磁盘 } } // PersistentStorage 持久化 AppStorage 键到磁盘应用重启后状态仍存在跨启动状态localStorage 魔法 vs 持久化状态存储槽的区别React 把持久化状态当 localStorage 魔法JSON 序列化到磁盘ArkTS 把 PersistentStorage 当「持久化状态存储槽」持久化 AppStorage 键到磁盘。根因不是 localStorage 魔法是持久化状态存储槽——PersistentStorage 持久化 AppStorage 键到磁盘应用重启后状态仍存在跨启动状态。二、根因PersistentStorage 的持久化状态存储槽机制鸿蒙 ArkUI 的 PersistentStorage 是持久化状态存储槽绑定——持久化 AppStorage 键到磁盘应用重启后状态仍存在跨启动状态来自三重绑定机制。机制 1PersistentStorage 持久化 AppStorage 键到磁盘——不是应用级内存PersistentStorage 荬饰器持久化 AppStorage 键到磁盘——应用重启后状态仍存在跨启动状态// ✅ 初始化 PersistentStorage持久化 AppStorage 键到磁盘 AppStorage.setOrCreate(persistCount, 0) PersistentStorage.persistProp(persistCount, 0) // ✅ 持久化 AppStorage 键到磁盘 Entry Component struct Index { StorageLink(persistCount) persistCount: number 0 // ✅ StorageLink 双向绑定持久化键 build() { Column() { Text(persistCount ${this.persistCount}) Button(改 persistCount) .onClick(() { this.persistCount }) // ✅ 改 → AppStorage 同步 → PersistentStorage 持久化到磁盘 } } } // PersistentStorage 持久化 AppStorage 键到磁盘应用重启后状态仍存在跨启动状态不丢持久化 AppStorage 键到磁盘PersistentStoragepersistCount持久化 AppStorage 键到磁盘——应用重启后persistCount仍存在跨启动状态不丢。根因不是应用级内存是持久化状态存储槽——PersistentStorage 持久化 AppStorage 键到磁盘应用重启后状态仍存在跨启动状态。机制 2StorageLink 双向绑定持久化键——改互同步持久化到磁盘StorageLink 荬饰器双向绑定持久化键——改 StorageLink → AppStorage 同步 → PersistentStorage 持久化到磁盘Entry Component struct Index { StorageLink(persistCount) persistCount: number 0 // ✅ StorageLink 双向绑定持久化键 build() { Column() { Text(persistCount ${this.persistCount}) Button(改 persistCount) .onClick(() { this.persistCount }) // ✅ 改 → AppStorage 同步 → PersistentStorage 持久化到磁盘 } } } // StorageLink 双向绑定持久化键改 → AppStorage 同步 → PersistentStorage 持久化到磁盘跨启动StorageLink 双向绑定持久化键StorageLinkpersistCount荬饰器双向绑定持久化键——改persistCount→ AppStorage 同步 → PersistentStorage 持久化到磁盘跨启动。根因不是只 AppStorage 同步是持久化到磁盘——StorageLink 双向绑定持久化键改 → AppStorage 同步 → PersistentStorage 持久化到磁盘。机制 3AppStorage.set 改 → PersistentStorage 同步持久化——不用 StorageLink 也能持久化AppStorage.set改 AppStorage 键→ PersistentStorage 同步持久化到磁盘不用 StorageLink 也能持久化Entry Component struct Index { StorageLink(persistCount) persistCount: number 0 // ✅ StorageLink 双向绑定持久化键 build() { Column() { Text(persistCount ${this.persistCount}) Button(直接改 AppStorage.set(persistCount, 999)) .onClick(() { AppStorage.set(persistCount, 999) // ✅ AppStorage 改 → PersistentStorage 同步持久化到磁盘 }) } } } // AppStorage.set 改 → PersistentStorage 同步持久化不用 StorageLink 也能持久化到磁盘AppStorage.set 改 → PersistentStorage 同步持久化AppStorage.setpersistCount改 AppStorage 键 → PersistentStorage 同步持久化到磁盘不用 StorageLink 也能持久化。根因不是必须用 StorageLink 是 AppStorage.set 直接改——AppStorage.set 改 → PersistentStorage 同步持久化到磁盘。机制 4PersistentStorage vs AppStorage 边界——跨启动 vs 应用级PersistentStorage持久化状态应用重启后状态仍存在跨启动AppStorage应用级状态所有页面共享页面卸载状态仍存在不跨启动——根因都是状态存储但绑的机制不同// ✅ PersistentStorage 路径持久化状态应用重启后状态仍存在跨启动 AppStorage.setOrCreate(persistCount, 0) PersistentStorage.persistProp(persistCount, 0) // ✅ 持久化到磁盘 Entry Component struct PersistPage { StorageLink(persistCount) persistCount: number 0 // ✅ 持久化键跨启动 build() { Button(持久化 ${this.persistCount}).onClick(() { this.persistCount }) } } // ✅ PersistentStorage 持久化状态应用重启后状态仍存在跨启动持久化到磁盘 // ⚠ AppStorage 路径应用级状态所有页面共享页面卸载状态仍存在不跨启动 AppStorage.setOrCreate(appCount, 0) Entry Component struct AppPage { StorageLink(appCount) appCount: number 0 // ⚠ 应用级键不跨启动应用重启销毁 build() { Button(应用级 ${this.appCount}).onClick(() { this.appCount }) } } // ⚠ AppStorage 应用级状态所有页面共享页面卸载状态仍存在不跨启动内存应用重启销毁PersistentStorage vs AppStorage 边界PersistentStorage 路径——持久化状态应用重启后状态仍存在跨启动持久化到磁盘。AppStorage 路径——应用级状态所有页面共享页面卸载状态仍存在不跨启动内存应用重启销毁。根因都是状态存储但绑的机制不同——PersistentStorage 持久化状态存储槽跨启动AppStorage 应用级状态存储槽不跨启动。三、真机配图PersistentStorage 持久化状态边界——跨启动状态初始态persistCount0 葝色、持久化状态边界初始态齐点调两按钮后persistCount999 葝色被 AppStorage.set 直接改 999 覆盖、PersistentStorage 持久化状态边界证据齐对比证据点改 persistCount 后 AppStorage 同步 PersistentStorage 持久化到磁盘StorageLink 双向同步点直接改 AppStorage.set(“persistCount”, 999) 后 persistCount999 被 AppStorage.set 直接改 999 覆盖 PersistentStorage 同步持久化到磁盘。PersistentStorage 持久化状态——持久化 AppStorage 键到磁盘应用重启后状态仍存在跨启动状态StorageLink 双向绑定持久化键AppStorage.set 改 → PersistentStorage 同步持久化。四、真解法PersistentStorage 持久化状态的三个场景场景 1PersistentStorage 持久化用户偏好90% 场景首选跨启动状态用持久化AppStorage.setOrCreate(themeColor, #007DFF) PersistentStorage.persistProp(themeColor, #007DFF) // ✅ 持久化用户偏好到磁盘 Entry Component struct Index { StorageLink(themeColor) themeColor: string #007DFF // ✅ StorageLink 双向绑定持久化键 build() { Column() { Text(themeColor ${this.themeColor}).fontColor(this.themeColor) Button(改 themeColor红色) .onClick(() { this.themeColor #FF4D4F }) // ✅ 改 → AppStorage 同步 → PersistentStorage 持久化到磁盘 } } }为哈能跑PersistentStorage 持久化用户偏好——持久化状态存储槽PersistentStoragethemeColor持久化 AppStorage 键到磁盘StorageLink 双向绑定持久化键改themeColor→ AppStorage 同步 → PersistentStorage 持久化到磁盘跨启动。首选这个90% 的场景跨启动状态用 PersistentStorage 持久化状态存储槽就够。要写「跨启动状态用户偏好等」时用这个——不用 AppStorage 应用级不跨启动PersistentStorage 持久化到磁盘跨启动。场景 2PersistentStorage 持久化登录状态跨启动状态应用重启仍登录AppStorage.setOrCreate(isLoggedIn, false) PersistentStorage.persistProp(isLoggedIn, false) // ✅ 持久化登录状态到磁盘 Entry Component struct Index { StorageLink(isLoggedIn) isLoggedIn: boolean false // ✅ StorageLink 双向绑定持久化键 build() { Column() { Text(isLoggedIn ${this.isLoggedIn}) Button(登录) .onClick(() { this.isLoggedIn true }) // ✅ 改 → AppStorage 同步 → PersistentStorage 持久化到磁盘 Button(退出) .onClick(() { this.isLoggedIn false }) // ✅ 改 → AppStorage 同步 → PersistentStorage 持久化到磁盘 } } } // PersistentStorage 持久化登录状态应用重启仍登录跨启动状态持久化到磁盘为哈能跑PersistentStorage 持久化登录状态——持久化状态存储槽PersistentStorageisLoggedIn持久化 AppStorage 键到磁盘StorageLink 双向绑定持久化键改isLoggedIn→ AppStorage 同步 → PersistentStorage 持久化到磁盘跨启动。要写「跨启动状态登录状态等」时用这个——不用 AppStorage 应用级不跨启动PersistentStorage 持久化到磁盘跨启动应用重启仍登录。场景 3PersistentStorage vs AppStorage vs LocalStorage 作用域边界跨启动 vs 应用级 vs 页面级// ✅ PersistentStorage 跨启动应用重启后状态仍存在持久化到磁盘跨启动状态用这个 AppStorage.setOrCreate(persistState, 0) PersistentStorage.persistProp(persistState, 0) // ✅ 跨启动持久化到磁盘 Entry Component struct PersistComp { StorageLink(persistState) persistState: number 0 // ✅ 跨启动应用重启仍存在 build() { Button(跨启动 ${this.persistState}).onClick(() { this.persistState }) } } // ✅ AppStorage 应用级所有页面共享页面卸载状态仍存在不跨启动内存应用级状态用这个 AppStorage.setOrCreate(appState, 0) Entry Component struct AppComp { StorageLink(appState) appState: number 0 // ✅ 应用级所有页面共享不跨启动 build() { Button(应用级 ${this.appState}).onClick(() { this.appState }) } } // ✅ LocalStorage 页面级同页面多组件共享页面卸载就销毁内存页面级状态用这个 interface LocalState { pageState: number } const localStorage new LocalStorage({ pageState: 0 } as LocalState) Component struct PageComp { LocalStorageLink(pageState) pageState: number 0 // ✅ 页面级同页面共享页面卸载就销毁 build() { Button(页面级 ${this.pageState}).onClick(() { this.pageState }) } } // PersistentStorage vs AppStorage vs LocalStorage 作用域边界 // 跨启动用 PersistentStorage持久化到磁盘应用级用 AppStorage内存不跨启动页面级用 LocalStorage内存页面卸载销毁为哈能跑PersistentStorage vs AppStorage vs LocalStorage 作用域边界——跨启动状态用 PersistentStorage持久化到磁盘应用重启仍存在应用级状态用 AppStorage内存不跨启动所有页面共享页面级状态用 LocalStorage内存页面卸载销毁同页面多组件共享。要写「选对状态存储槽作用域跨启动 vs 应用级 vs 页面级等」时用这个——跨启动用 PersistentStorage应用级用 AppStorage页面级用 LocalStorage。五、一句话哲学PersistentStorage 不是应用级 AppStorage是持久化到磁盘的跨启动状态存储槽。ArkUI 的 PersistentStorage 荬饰器持久化 AppStorage 键到磁盘应用重启后状态仍存在跨启动状态。根因不是应用级 AppStorage 是持久化状态存储槽——PersistentStorage 持久化 AppStorage 键到磁盘应用重启后状态仍存在跨启动状态 StorageLink 双向绑定持久化键改 → AppStorage 同步 → PersistentStorage 持久化到磁盘 AppStorage.set 改 → PersistentStorage 同步持久化不用 StorageLink 也能持久化到磁盘 PersistentStorage vs AppStorage 边界跨启动 vs 应用级。对比 React 持久化状态 localStorage 魔法JSON 序列化到磁盘ArkTS PersistentStorage 持久化状态存储槽跨启动状态。状态联动深水区串讲Watch 绑 State 变触发副作用回调槽篇 68 Link $ 语法双向绑定跨组件同步篇 69 Provide/Consume 跨层级传递槽祖辈后辈同步篇 70 Observed/ObjectLink 嵌套对象观测槽子属性改刷 UI篇 71 AppStorage 应用级状态存储槽所有页面共享篇 72 LocalStorage 页面级状态存储槽同页面多组件共享篇 73 StorageLink/StorageProp 应用级状态绑定边界双向 vs 只读篇 74 LocalStorageLink/LocalStorageProp 页面级状态绑定边界双向 vs 只读篇 75 状态管理装饰器全景边界 V1/V2 双轨篇 76 PersistentStorage 持久化状态存储槽跨启动状态篇 77应用重启后状态仍存在——续「ArkUI 状态联动」深水区讲状态联动深水区Watch 副作用回调槽边界 Link $ 语法双向绑定边界 Provide/Consume 跨层级传递槽边界 Observed/ObjectLink 嵌套对象观测槽边界 AppStorage 应用级状态存储槽边界 LocalStorage 页面级状态存储槽边界 StorageLink/StorageProp 应用级状态绑定边界 LocalStorageLink/LocalStorageProp 页面级状态绑定边界 状态管理装饰器全景边界 V1/V2 双轨 PersistentStorage 持久化状态存储槽边界。系列预告下篇篇 78讲 Environment 环境变量状态边界环境变量注入根因续「ArkUI 状态联动」深水区。五阶段哲学体系类型哲学50-52→ 作用域哲学53-55→ 状态哲学56-59→ 渎染哲学60-62→ 组件设计63-67→ 状态联动深水区68讲清 ArkTS/ArkUI 进阶哲学。能力系列回链能力系列篇本文进阶点篇 28 PersistentStorage 用法PersistentStorage 持久化状态存储槽边界根因跨启动状态持久化到磁盘篇 23 AppStorage 用法应用级状态存储槽边界所有页面共享页面卸载状态仍存在不跨启动篇 59 Watch 用法状态联动深水区Watch 副作用回调槽 vs onClick 直接调副作用边界真机 demo 完整代码// 篇 77 demoPersistentStorage 持久化状态边界 // PersistentStorage 持久化 AppStorage 键到磁盘——应用重启后状态仍存在跨启动状态 AppStorage.setOrCreate(persistCount, 0) PersistentStorage.persistProp(persistCount, 0) // ✅ 持久化 AppStorage 键到磁盘API 21 用 persistProp Entry Component struct Index { StorageLink(persistCount) persistCount: number 0 // ✅ StorageLink 双向绑定持久化键 State log: string (未操作) build() { Column({ space: 12 }) { Text(篇 77 配图PersistentStorage 持久化状态边界) .fontSize(16).fontWeight(FontWeight.Bold).margin({ top: 16, bottom: 4 }) Text(PersistentStorage 持久化 AppStorage 键到磁盘——应用重启后状态仍存在跨启动状态) .fontSize(10).fontColor(#888).margin({ bottom: 8 }) Column({ space: 6 }) { Text(持久化状态PersistentStorage) .fontSize(12).fontColor(#2563eb).fontWeight(FontWeight.Bold) Text(persistCount ${this.persistCount}) .fontSize(15).fontWeight(FontWeight.Bold).fontColor(#2563eb) Text(应用重启后仍存在——跨启动状态) .fontSize(10).fontColor(#888) } .width(92%).padding(10).backgroundColor(#e0f0ff).borderRadius(8) Button(改 persistCount持久化到磁盘) .width(92%).height(40).fontSize(12) .onClick(() { this.persistCount // ✅ 改 → AppStorage 同步 → PersistentStorage 持久化到磁盘 this.log 改 persistCount${this.persistCount}持久化到磁盘重启仍存在 }) Button(直接改 AppStorage.set(persistCount, 999)) .width(92%).height(40).fontSize(12) .onClick(() { AppStorage.set(persistCount, 999) // ✅ AppStorage 改 → PersistentStorage 同步持久化 this.log 直接改 AppStorage.set persistCount999持久化同步 }) Text(日志${this.log}).fontSize(10).fontColor(#333).margin({ top: 4 }) Text(对比AppStorage 应用级状态页面卸载状态仍存在vs PersistentStorage 持久化状态应用重启仍存在) .fontSize(10).fontColor(#ff6600).margin({ top: 8 }) } .width(100%).height(100%).alignItems(HorizontalAlign.Center) } }写鸿蒙 ArkUI 记住PersistentStorage 不是应用级 AppStorage 是持久化到磁盘的跨启动状态存储槽——PersistentStorage 荬饰器持久化 AppStorage 键到磁盘应用重启后状态仍存在跨启动状态。根因不是应用级 AppStorage 是持久化状态存储槽——PersistentStorage 持久化 AppStorage 键到磁盘应用重启后状态仍存在跨启动状态 StorageLink 双向绑定持久化键改 → AppStorage 同步 → PersistentStorage 持久化到磁盘 AppStorage.set 改 → PersistentStorage 同步持久化不用 StorageLink 也能持久化到磁盘 PersistentStorage vs AppStorage 边界跨启动 vs 应用级。PersistentStorage 持久化用户偏好用持久化状态存储槽首选90% 场景PersistentStorage 持久化登录状态用持久化状态存储槽跨启动应用重启仍登录PersistentStorage vs AppStorage vs LocalStorage 作用域边界选对存储槽跨启动用 PersistentStorage 持久化到磁盘应用级用 AppStorage 内存不跨启动页面级用 LocalStorage 内存页面卸载销毁。持久化到磁盘跨启动状态应用重启仍存在是 ArkUI 状态联动深水区核心

相关新闻

2026/7/31 17:57:49

2021年12月青少年C/C++软件编程(三级)等级考试试卷及答案解析

目录 1.我家的门牌号 2.子串计算 3.吃糖果 4.拨钟问题 5.分形盒 1.我家的门牌号 我家住在一条短胡同里,这条胡同的门牌号从1开始顺序编号。 若所有的门牌号之和减去我家门牌号的两倍,恰好等于n,求我家的门牌号及总共有多少家。 数据保证有唯一解。 时间限制:1000 …

2026/7/31 17:57:49

3个关键问题告诉你为什么Etcher是镜像烧录的最佳选择

3个关键问题告诉你为什么Etcher是镜像烧录的最佳选择 【免费下载链接】etcher Flash OS images to SD cards & USB drives, safely and easily. 项目地址: https://gitcode.com/GitHub_Trending/et/etcher 在嵌入式开发、树莓派项目或系统部署的日常工作中&#xff…

2026/7/31 18:52:52

银河麒麟V10 PAM认证详解:开启PAM日志+登录安全策略(等保必备)

麒麟V10系统pam文件解析 Pam配置 一、简介 二、工作原理 三、PAM的配置文件说明 1)第一列:PAM的模块类型 2)第二列:PAM的控制标记 3)模块路径 4)模块参数 四、PAM模块的工作原理和流程 五、常用的pam模块介绍 六、PAM模式使用 1)pam_access.so模块 2)pam_listfile.so 示…

2026/7/31 18:52:52

Android Studio中Compse界面使用LayoutInspector报错

最近换了电脑,然后把开发环境重新搭建了一下,基本完成后,连接设备准备看看一个UI布局的问题。我用的是Compose写的界面,当我尝试用LayoutInspector的时候居然报错失败了,界面提示:Could not download andro…

2026/7/31 18:47:52

springboot 学校设备管理系统

一、关键词学校设备管理系统、学校设备、学校设备信息管理、学校设备后台管理二、作品包含源码数据库设计文档全套环境和工具资源本地部署教程三、项目技术前端技术: Html、Css、Js、Vue3.4、Element-Plus后端技术:Java、SpringBoot3.0.0、MyBatis-Plus四…

2026/7/29 22:32:30

PDF合并与动态水印的工程化方案:2026国内免费工具实测对比

一、背景与测试方案 在实际项目交付中,PDF文件合并与版权保护水印的叠加是一个高频但容易被低估的技术需求。典型的处理链路涉及:多源PDF的文件流合并、页面级水印渲染(含透明度混合与图层叠加)、输出文件体积控制。看似简单的操作…

2026/7/31 0:01:11

物理复制比逻辑复制好在哪?数据库复制原理详解

数据库复制是把主库数据同步到备库的机制,分为逻辑复制和物理复制两种。逻辑复制传输的是 SQL 语句或行变更事件,物理复制传输的是存储引擎底层的物理日志。阿里云 PolarDB(云原生数据库)采用物理复制,在同步延迟、数据…

2026/7/31 0:01:11

BilibiliDown:3分钟学会B站视频下载的终极指南

BilibiliDown:3分钟学会B站视频下载的终极指南 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirrors/bi/Bilib…

2026/7/31 0:01:11

有哪些游戏数据AI平台?游戏行业Data+AI融合方案盘点

当前,游戏行业的“DataAI融合”已从概念验证进入价值落地阶段。根据IDC 2025年数据,中国AI游戏云市场规模已达18.6亿元;同时,游戏研发环节AI渗透率高达86%,生成式AI内容普及率超过50%。面对庞大的市场,游戏…

2026/7/31 0:38:56

3个高效策略:快速掌握Axure中文界面配置

3个高效策略:快速掌握Axure中文界面配置 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文界面感…