随着鸿蒙Next的发布,慢慢的变多的APP开始推进鸿蒙化适配,产品与技术团队也启动了游戏电竞直播SDK的鸿蒙适配规划。投入充足资源通常能达成适配目标,但仅实现技术目标的意义相对单薄 —— 如何进一步升华价值、让鸿蒙适配效益最大化?本文将介绍基于Kuikly框架的鸿蒙跨端适配方案,实现SDK业务代码100%跨三端跨多游戏App复用,相比各端独立开发,可节省 50% 以上人力,明显提升开发效率。 其中Kuikly是腾讯普遍的使用的跨端开发框架,提供了使用Kotlin语言开发Android、iOS、鸿蒙、Web、小程序跨端应用能力,也是腾讯端服务联盟的重要成员。
游戏电竞直播SDK是一个有着很长历史的电竞赛事直播基础组件,在CODM,QQ飞车,极品飞车,元梦之星,AOV等游戏APP中都有使用。游戏电竞直播SDK在这些游戏APP上的产品形态非常相似。为提升跨多端、跨多APP的研发效率,我们也在力争做到同一份代码尽可能复用到不同游戏APP中。
![]()
![]()
新增鸿蒙版本的开发,在适配阶段需要投入较大成本对齐安卓/iOS能力,同时后期也要增加一套鸿蒙人力持续开发迭代。在此背景下,团队需要思考怎么样选择适配方案,以降低适配成本、甚至放大适配价值。
从研发效率提升为出发点,团队设定了适配目标:既要低成本适配鸿蒙系统,又要让适配工作价值最大化。
游戏电竞直播SDK和Kuikly技术团队合作快两年,Android和iOS在多个项目(CODM、QQ飞车、极品飞车)已经基于Kuikly实现了业务跨端,跨业务线开发。针对鸿蒙系统,Kuikly同样是较早完成适配,并在浏览器、K歌等多业务完成验证打磨,因此这次鸿蒙适配也是基于这个司内优秀跨端框架作为基础搭建。
对比Android,鸿蒙的三方文档相对较少。为了确认和保证后面制定技术方案不可能会出现较大纰漏,还是稳扎稳打的抽时间学习了鸿蒙开发基础。ArkTs,自定义组件,声明式布局开发,多线程,多进程开发等基础能力都需要提前补齐。
![]()
如上图是鸿蒙入门的基础知识点,只需掌握基础的,更进阶的编程要点在开发过程中通过官方文档,元宝AI搜索基本都可解决。为验证学习效果,基于鸿蒙UI框架花费了约1d的时间简单搭建一个电竞直播SDK主体框架,目的是验证学习效果是否达标,并且基于这个做组内分享,让团队人员也能够基于熟悉的项目快速入门鸿蒙开发,方便后期对齐技术方案。
![]()
![]()
游戏电竞直播SDK的Android,iOS已经深度使用Kuikly组件,稳定性,混合开发特性,性能,包体积等方面都有较好实测体验。
对比方案后选择“KuiklyUI实现业务,KuiklyBase实现逻辑组件”的方案更加合适。
![]()
原生层的开发是避免不了的工作,这里我们也选择将通用逻辑做跨端处理,使用了KMP的开发范式。主体思想即“求大同,存小异”。
我们将“大同”的部分规划到用Kotlin开发,实现跨端调用。“小异”部份用特定的平台层编程语言开发。
![]()
如图中可见,最底层只有一个很”薄“的鸿蒙原生页面,这个页面是一个Entry装饰的page组件,不是Ability。
![]()
如上图所示是电竞直播SDK业务层整体框架设计,其中页面路由很有特点,不是基于Kuikly的官方的路由组件,而是自己封装的基于KuiklyNativeView实现的页面路由,由于Kuikly很灵活,可以让研发人员把任意原生View按照Kuikly协议映射为Kuikly可以布局使用的KuiklyView,这里简称为KuiklyNativeView。
目标是将游戏电竞直播业务实现100%跨端,必须将之前原生层的业务模块嵌入到Kuikly中。基于Kuikly的自定义组件接口协议,我们封装了一些必要组件到Kuikly使用。
![]()
![]()
如上是将一个KuiklyPage 嵌入到一个鸿蒙原生的View中,相当于业务方实现了以View为单位的最小粒度去使用KuiklyPage,并且还按照KuiklyPage规范,封装成了一个KuiklyNativeView,让KuiklyPage里面可以套娃方式嵌套使用KuiklyPage。效果类似Android的Frament组件。这种使用方式是Kuikly官方没有支持的特性,在Android上已经通过Fragment实现同等效果,积累了经验并且验证了稳定性,在鸿蒙上直接再次复刻了能力。这个特性让电竞直播SDK主页面可以自由嵌套多个任意大小,位置,层级的KuiklyPage完成需求开发,也为后续说的需求特性模块化共享留下技术支撑。
电竞直播SDK大厅业务大部分需要撑满全屏,还有一种非全屏特殊场景,即在游戏的Unity页面上以非全屏浮层方式呈现活动页面。类似那种广告弹窗等。由于鸿蒙上实现透明页面需要Ablity层级的组件,但是这种组件对游戏电竞直播SDK而言太“重”了,因此采用了弹窗方式。
![]()
如上图展示的层级关系,用鸿蒙原生自定义全屏透明弹窗作为容器承载KuiklyNativeView,如此就可以让Kuiky业务自己决定显示哪些内容到游戏画面上,并能控制透明区域的大小位置。
游戏电竞直播SDK核心玩法之一是游戏赛事直播,播放器会被重度使用。在Android和iOS老项目上,我们采用了混合开发,播放页面依然使用原生容器Activity/ViewController实现,然后再在上面安装Kuikly的插槽。这种方案缺陷很多,例如原生和Kuikly之间的事件,方法双向调用很繁琐,需要做很多胶水层代码,桥接层很重。
![]()
本次鸿蒙适配过程中,直接反向思维,将必要的原生组件嵌入到Kuikly页面中。如上图所示,我们参照KuiklyNativeView的实现思路,将播放器所在的View直接封装到Kuikly中,实现一个KuiklyPlayerView。这样播放器的生命周期,层级,大小,位置都交由宿主KuiklyPager管理。
弹幕也是重要的运营工具,为了方便业务闭环运营,参照播放器一样封装映射为Kuikly组件使用。
![]()
如上图所以,游戏电竞直播SDK是一个强运营特性的SDK,常常会出现A游戏实验不错的运营玩法会铺开到其他其他游戏中使用。这样一个时间段玩法特性按需放到不同游戏的游戏电竞直播SDK中就很有必要了。如下介绍特性跨产品线配置化实现方式
![]()
如上图A所示,当ABCD四个特性代码都寄存在同一个Activity时候,第一个研发人员可能会保持各个特性实现尽量做到低耦合,但是代码经手多人后,这种“弱耦合”的代码最终会演变为“强耦合”,甚至成为一团乱麻的债务。
KuiklyPager有一个特点,即两个KuiklyPager之间的数据共享成本很高,无法直接通过静态变量传递数据,官方手段是通过启动参数共享数据,或者通过事件总线共享数据和事件。并且两个KuiklyPager之间无法通过持有对方的引用调用接口。这种高门槛的数据共享,禁止对象互相持有的特性,刚好天然实现了KuikyPager之间的弱耦合特性。研发人员想制造毛球代码都很难。
![]()
如上是Kuikly官方文档提到的Pager的生命周期,由于每个特性独占一个KuiklyPager,需求特性所需要的基本要素都满足了,自然很少会去耦合其他模块的代码。且其轻量化的底层设计也使得资源额外开销可以忽略。
既然ABCD之间和耦合很弱,那么之间的交互关系怎么完成呢?用到了业界很成熟的方案,即Scema跳转。电竞直播SDK的Schema路由跳转经历了1.0版本的初步引入使用,展示了其友好的运营可配置化特性,2.0版本逐步加强了Schema配置管理端的建设,降低了Schema暴增后的管理维护难度。
很多事遵从二八法则,通过投入少量精力制定规范化的运营迭代流程,就能解决很多技术上需要投入巨大资源才能做到的事情。很多历史债务是由于迭代期间逐步积累的,我们已实现了Kuikly业务的弱耦合开发规范,接下来看下更多规范制定。
Kuikly框架是一个跨平台UI框架,一些系统接口能力还是需要原生提供桥接层代码实现。
![]()
如上图是遵从惯性思维实现原生层的API给Kuikly业务层使用,提前写了一堆if-else代码,导致原生层很“厚重”,绑定业务的原生API也很难复用到别的业务特性上。
![]()
优化的设计如上图,原生尽可能提供必要的原子接口,让原生层做得更“轻薄”。
基于前面提到的种种特性,业务尽可能提升到Kuikly层实现,原生只提供必要的原子接口即可。再配合Schema配置管理端,流水线发布规范,需求评审流程规范等。这套流程已经在游戏电竞直播SDK上稳定运行1年多,鸿蒙项目继续复刻这套研发流程。
![]()
本次鸿蒙平台适配,所有业务代码通过Kuikly跨端为基础,补齐基建能力,流程规范,进而实现了业务代码100%跨三端、跨多App共享。得益于Kuikly框架对鸿蒙平台适配的功能完善度、高性能、动态化和稳定能力等各维度优异表现,也让我们快速完成初版适配,并在性能和产品体验上达到了预期效果。
当前Kuikly已经开源,有兴趣和有需要的产品,能够最终靠以下方式了解详情或接入体验:
