探究APP换肤机制的设计与实现

从产品的前瞻性上来看,国内在换肤功能的探索较国外是领先的,抽象的来看待Android Q的深色模式,也无非是新增一种主题罢了,因此,开发者应该将角度放在更高的层级上:为产品提供一套完善的换肤方案,而非仅仅是适配深色模式 。

想清楚这一点,开发者就不会将目光仅局限于技术本身——对于整个换肤体系而言,涵盖了UI、产品、开发、测试、运维等多名角色不同的关注点,而这些关注点最终却都依赖研发协助做决策,举例如下:

  • UI:定义不同的UI组件不同的颜色属性,这些属性最终在不同的主题下,代表不同的颜色(日间模式下标题是黑色,但是夜间模式下,标题应该是白色)。

  • 产品:定义换肤功能的业务流程,从简单的换肤主页,换肤的交互,到不同主题下的不同展示、付费策略等等。

  • 开发:提供换肤功能的研发能力。

  • 测试:保证换肤功能的稳定性,比如自动化测试和便捷取色工具。

  • 运维:保证线上问题的快速定位和及时解决。

除此之外,还有更多可以深入思考的技术点,比如,随着主题越来越多,势必导致APK包体积的增大,是否有必要引入远程动态加载(download & install)的能力助不同角色的视角,我们可以提前规划好远景,接下来的编码也就更加遂心应手。

/   定义UI规范   /

换肤规范的目的是什么于UI设计和开发人员而言,设计与开发都应该基于统一且完整的规范之上进行,以掘金APP为例:

这对于开发人员的效率提升更加明显,开发者不再需要关心具体颜色的值,只需要将对应的color填充到布局中即可:

/   构建产品化思维:皮肤包   /

如何衡量一个开发人员的能力——对复杂功能快速、稳定的交付/p>

如果只是单纯的认可这个理念,那么对于换肤功能的实现反而简单了,以标题颜色skinPrimaryTextColor为例,我只需要声明两个color资源:

笔者成功摆脱了复杂的编码实现,在Activity中我只需2行代码即可:

这种实现并非一无是处,从实现的难度而言,至少能够保护开发者为数不多的发囊。

当然,这种方案有优化空间,比如提供封装的工具方法看似摆脱无尽的if-else:

很明显,return colorRes + “_Dark”这行代码作为int类型的返回值是不成立的,读者无需关注具体实现,因为这种封装仍未摆脱笨重的 if-else 实现的本质。

可以预见,随着主题数量逐步增多,换肤相关的代码越来越臃肿,最关键的问题是,所有控件的相关颜色都强耦合于换肤相关代码本身,每个UI容器(Activity/Fragment/自定义View)等需要追加Java代码手动设置。

此外,当皮肤数量达到一定规模时,color资源的庞大势必影响到apk体积,因此主题资源的动态加载发势在必行,用户安装应用时默认只有一个主题,其它主题按需下载和安装 ,比如淘宝:

读者不禁会问,动态刷新的意义是什么 ,让当前页面重建或者APP重启不行吗/p>

当然可行,但是不合理 ,因为页面重建意味着页面状态的丢失,用户无法接受一个表单页面已填信息被重置;而如果要弥补这个问题,对每个页面重建追加状态的保存(Activity.onSaveInstanceState()),在实现的角度来看,也是一个巨大的工程量。

因此动态刷新势在必行——用户无论是在应用内切换了皮肤包,还是手动切换了系统的深色模式,我们如何将这个通知进行下发,保证所有页面都完成对应的刷新呢/p>

保存所有页面的Activity

读者知道,我们可以通过Application.registerActivityLifecycleCallbacks()方法观察到应用内所有Activity的生命周期,这也意味着我们可以持有所有的Activity:

有了所有的Activity的引用,开发者就可以在接到换肤通知的时候,第一时间尝试让所有页面的所有View去更新换肤。

成本问题

但巨大的谜团随之映入眼帘,对于控件而言,更新换肤这个概念本身并不存在。

什么意思呢换肤通知到达时,我无法令TextView更新文字颜色,也无法令View更新背景颜色——它们都只是系统的控件,执行的都是最基础的逻辑,说白了,开发者根本无法进行编码。

有同学说,那我直接让整个页面的整个View树所有View都全部重新渲染可以吗以,但是又回到了最初的问题,那就是所有View本身的状态也被重置了(比如EditText的文字被清零),退一步讲,即使这一点可以被接受,那么整个View树的重新渲染也会极大影响性能。

那么,如何尽可能的 节省页面动态刷新的成本/strong>

开发者希望,换肤发生时,只对指定控件的指定属性进行动态更新,比如,TextView只关注更新background和textColor,ViewGroup只关注background,其他的属性不需要重置和修改,将设备的每一分性能都利用到极致:

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年6月25日
下一篇 2021年6月25日

相关推荐