主题切换的经验浅谈
线上排过一类「假成功」:SwitchSuit 返回成功,预览名也变了,表盘还是旧的。根子往往不在接口,而在你手里那棵树是不是管理器认识的那棵。接口只保证「套名写进去了、通知发出去了」,并不保证你屏幕上那棵树在听众名单里。
设计选择很明确:外面拿到的 ThemeRoot 指针尽量不变,变的是肚子里的孩子。根已经挂在 ui_lite 的父容器上,若每次换套都 new 一个根再塞回去,业务要改挂载,生命周期也容易乱,野指针跟着来。所以切换是同步做完的:先把当前套名写入配置,通知外部用 C 回调订过套变更的人,再通知管理器里所有已登记的根。每个根 Stop 注销数据、ClearAllViews 拆旧视图、按 key 重新解析 theme_info.json、换掉 header、再 Start、最后 Invalidate。返回的那一刻,树上应该已经是新皮肤,不是丢到后台慢慢刷。这对嵌入式很重要:调用方可以假定切完就能画,而不必再轮询「换好了没有」。
登记发生在 CreateThemeByKey 的构造路径里。自己 new 一棵树,切套日志里可能只有套名,没有 OnThemeChanged,画面当然装聋。同名再切一次会走短路,通知还在发,但别指望配置文件给你新线索。排障时不要只盯返回值,要对着 HiLog 看根有没有走进更新。外部订阅者适合刷新预览、记埋点,不要在回调里做重活,更不要把套名那个临时指针存下来。
如果切完立刻 Destroy 再 Create,表面上也能换皮肤,但你等于放弃了这套「根稳住」的约定,父容器和数据回调都要自己再绑一遍,得不偿失。
磁盘上的「更新套」是另一条故事:先解到临时目录,删旧再改名,失败就丢掉临时目录,避免半套皮肤留盘。内存里换树、磁盘里换货,先分清你在哪一层。切套查实例名单,更新查 ZIP 和目录权限,两件事搅在一起会越查越花。记住那句设计口诀:指针不变,内容重建。
更多推荐
所有评论(0)