ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

HarmonyOS 多设备短视频开发 :24 — AppStorage/AppStorageV2 应用级状态

HarmonyOS 多设备短视频开发 :24 — AppStorage/AppStorageV2 应用级状态 页面级状态由组件装饰器管理而跨页面、跨组件树、与应用同生命周期的全局状态需要专门容器V1 时代的 AppStorage 与 V2 时代的 AppStorageV2。本项目用 AppStorageV2 承载最关键的全局对象——窗口信息 WindowInfo由common/multishortvideobase/src/main/ets/utils/WindowUtil.ets统一维护同时用 Provider/Consumer 在页面根部构建 Provider 树共享路由栈、侧栏开关、深色模式等。本文对比 AppStorage 与 AppStorageV2 的差异结合项目代码讲解全局状态的最佳实践。二、AppStorage 基础与局限AppStorage 是 V1 的 UI 应用级状态容器单例驻留于 UIAbility 生命周期内支持简单类型与对象。V1 常用写法// V1 写法对照存储与读取全局属性AppStorage.setOrCreate(isDark,false);// 写入constisDarkAppStorage.getboolean(isDark);// 读取局限同样明显对嵌套对象需配合 Observed/ObjectLink 才能深层观察所有操作都走字符串 key缺少类型约束装饰器StorageLink/StorageProp与 V2 组件体系不兼容项目迁到 V2 后无法直接使用。因此在 V2 工程中AppStorage 仅作为兼容层存在新代码应使用 AppStorageV2。三、AppStorageV2 与 connect 连接AppStorageV2 以连接类对象为核心用 ObservedV2 装饰的类作为存储类型connect 建立连接后返回同一实例任何持有该实例的组件都能观察其 Trace 属性。WindowUtil.ets 中的实现// common/multishortvideobase/src/main/ets/utils/WindowUtil.ets真实代码import{AppStorageV2,UIContext,window}fromkit.ArkUI;exportconstWINDOW_INFO_STORAGE_KEYMultiShortVideoWindowInfo;ObservedV2exportclassWindowInfo{TracepublicwindowStatusType:window.WindowStatusTypewindow.WindowStatusType.UNDEFINED;TracepublicisFullScreen:booleanfalse;Tracepublicorientation:window.Orientationwindow.Orientation.UNSPECIFIED;TracepublicwindowSize:window.Size{width:0,height:0};TracepublicwidthBp:WidthBreakpointWidthBreakpoint.WIDTH_XS;TracepublicheightBp:HeightBreakpointHeightBreakpoint.HEIGHT_SM;...}exportfunctiongetWindowInfoState():WindowInfo{returnAppStorageV2.connectWindowInfo(WindowInfo,WINDOW_INFO_STORAGE_KEY,()newWindowInfo())!;}connect 的三个参数分别是存储类型、存储键、默认值工厂。首次调用创建并存入之后任何模块调用 getWindowInfoState() 拿到的都是同一实例由于类成员带 Trace属性修改会精确通知所有引用该对象的组件。WindowUtil 单例持有 mainWindowInfo 引用在窗口回调中就地修改属性publiconWindowSizeChange:(windowSize:window.Size)void(windowSize:window.Size){this.mainWindowInfo.windowSizewindowSize;this.mainWindowInfo.widthBpthis.uiContext!.getWindowWidthBreakpoint();this.mainWindowInfo.heightBpthis.uiContext!.getWindowHeightBreakpoint();};组件侧只需Local windowInfo: WindowInfo getWindowInfoState()即可在断点、避让区、沉浸状态变化时自动刷新无需任何手动通知——这是本项目断点驱动自适应布局的状态基石。四、Provider/Consumer 树页面级全局状态的分工AppStorageV2 解决应用级、跨模块状态页面内跨组件通信则交给 Provider/Consumer 树二者分工如下状态载体生命周期示例窗口信息、避让区AppStorageV2 WindowInfo整个应用widthBp、statusBarTopVp主题/侧栏/路由Provider/Consumer页面/路由栈isDark、showSideComment播放进度Provider/Consumer视频页组件树currentTime、durationproducts/default/src/main/ets/view/Index.ets在根组件构建 Provider 树EntryComponentV2struct Index{LocalwindowInfo:WindowInfogetWindowInfoState();Provider(isDark)isDark:booleanfalse;Provider(pathStack)pathStack:NavPathStacknewNavPathStack();Provider(showSideComment)showSideComment:booleanfalse;Provider(showSideIndividual)showSideIndividual:booleanfalse;...}视频页 AdaptiveVideo.ets 与播放器 AdaptiveAVPlayer.ets 则跨层消费/转发Consumer(showSideComment)、Consumer(currentTime)等。当用户在大屏点击评论图标时AdaptiveVideo 修改 showSideComment 并 pushPathByName(‘SplitComment’)根组件 Navigation 随即切换为分栏模式点击空白区域时根组件的手势判定会 pop 路由并复位侧栏开关——Provider/Consumer 树让深层组件改、根部响应成为可能。值得注意的还有 AdaptiveVideo 的消费再提供模式它从根组件消费 pathStack 与侧栏开关同时把播放器上报的进度Consumer(‘currentTime’)/Consumer(‘duration’)以 Provider(‘windowSizeWidth’)/Provider(‘commentCount’) 等继续下发给更深层的 UI形成中转站。这比让每个深层组件都直接连接 AppStorageV2 更符合就近提供、按需消费的原则——AppStorageV2 只存放真正需要全局唯一的对象页面内部的共享数据留在组件树内既减少全局命名空间污染也让数据流的追踪路径保持在页面范围内。五、AppStorageV2 的更多能力与生命周期AppStorageV2 除 connect 外还提供 remove 等管理接口可用于在页面退出时解除连接// 解除指定 key 的连接AppStorageV2 管理接口AppStorageV2.removeWindowInfo(WINDOW_INFO_STORAGE_KEY);需要明确的是AppStorageV2 的生命周期与应用进程一致窗口信息这类从 Ability 启动持续到退出的状态无需手动 remove若某类全局状态只在特定页面存在如临时会话上下文则在页面销毁时 remove 并置空引用避免内存泄漏。此外AppStorageV2 存的是可观察对象ObservedV2 类与 V1 AppStorage 的值拷贝存储不同连接方拿到的是同一引用修改 Trace 属性即为修改全局状态这也要求写入方遵守单向数据流约定避免多处同时改写导致状态发散。六、跨组件通信的最佳实践全局唯一且跨模块共享 → AppStorageV2.connect如 WindowInfo。存储键用模块级常量WINDOW_INFO_STORAGE_KEY避免魔法字符串。页面内跨层共享 → Provider/Consumerkey 统一字符串命名Provider 尽量集中在页面根部Index.ets便于追溯。父子直连 → Param/Event能用 Param 传参就不用 Provider缩小影响面。AppStorageV2 存放可观察类对象而非散落的基本类型类对象配合 Trace 支持属性级刷新散落键值则难以组织与清理。AppStorageV2 与持久化解耦AppStorageV2 只存内存态进程内如需跨启动恢复断点、播放位置应配合 Preferences 落地见文章 25。七、总结与最佳实践V2 工程优先使用 AppStorageV2connect 连接 ObservedV2 类类型安全、属性级可观察、全模块共享。WindowInfo 是全局状态单例的教科书实现单例维护WindowUtil 全局存储AppStorageV2 组件观察Local getWindowInfoState三层协作。页面级共享状态主题、侧栏、路由用 Provider/Consumer 树收敛在根部避免滥用 AppStorageV2。新旧代码共存时V1 的 AppStorage 仅作兼容层不新增依赖。明确状态生命周期应用级状态进 AppStorageV2页面级状态进 Provider 树临时状态用 Local职责清晰才能保证多设备工程的可维护性。
返回列表