===================================================================
爱奇艺知识目前有多个业务承载端,包括爱奇艺移动端APP的知识插件、爱奇艺iPad端APP的知识插件、随刻移动端APP的知识插件和爱奇艺知识移动端独立APP。由于各个端上线的时间不同,所承载的业务功能也不完全一致,造成了多端多套代码的情况,维护成本很高。首先当相同或类似的功能需要迭代升级时,开发和测试都需要在多端同步进行,成本成指数级增长;其次随着业务的快速发展,业务模块在不断增加,模块间的依赖关系也变得越来越模糊,代码耦合度和复杂度都在增大;另外在现有人力成本的基础上如果想增加更多的业务端,就会变得非常困难。因此长期看非常不利于业务的高效迭代。下图描述了组件化之前,爱奇艺知识各端的业务模块架构。
从上图我们也能看出其实每个端之间是存在很多公共业务模块的,各个业务模块的底层支撑模块也几乎相同,所以结合爱奇艺知识自身的业务特点,我们提出了适合于爱奇艺知识移动端的组件化方案。
我们将组件化的目标定义为以下几个:
· 解决多端代码维护问题
根据业务特点,横向和纵向划分组件,以组件为单位承接迭代需求,各端进行组件复用;
· 解决跨组件调用和组件间路由的问题
业务划分更加清晰、组件间解耦更加彻底、组件间通信更高效,对原有业务模块进行抽离和整合,明确组件间的业务边界;
· 提升开发效率,方便开发调试
组件可以单独编译和调试,使模块开发者更聚焦本模块业务;
· 提升集成和提测效率
各端项目需要哪个组件,可以直接通过工具快速集成和提测。
基于以上目标,我们设计了适合爱奇艺知识业务的组件划分策略,下图为组件化之后的功能架构图,横向分为基础组件、功能组件和业务组件,纵向对每个层级的组件又进行细分;从划分粒度上看,组件不仅包括功能性的sdk,还可能包括业务UI,宗旨就是业务模块独立,边界清晰,方便扩展和维护。
====================================================================
基于功能架构,知识组件化的技术架构如下图所示。
最下层是基础组件,包括baselib和componentService,我们将网络库、pingback、数据库、日志和工具类等公共底层实现构成基础组件,屏蔽了系统和各端的差异,位于功能和业务组件的下层。所有功能和业务组件都使用同一套基础组件,可以保证公共部分的统一性。基础组件比较稳定,不会频繁迭代。
再往上一层是功能组件,如承载播放能力的播放器和历史记录组件、承载支付能力的支付和营销组件,、承载多端定制化分享能力的分享&海报组件等各个端都有的基础功能,功能组件位于基础组件和业务组件之间,功能组件会根据业务组件的需要而不断迭代升级。
接下来是业务组件,这层是各个端有可能包含也有可能不包含核心业务模块,为了开发和维护方便,我们将核心业务模块抽取为业务组件,如搜索、筛选、发现feed流、评论、评价、作业作品等,业务组件位于基础组件和功能组件的上层,迭代较频繁,但业务本身比较独立,边界清晰。
最上层是壳工程,各端都需要一个主工程负责集成所需要的组件,我们统称为壳工程,壳工程包括了各端的基础框架,比如组件注册和初始化逻辑,平台相关性处理逻辑等,还有各端特有的业务模块,不适合抽离和拆解的部分。
右侧是负责管理组件间交互和跳转的MoudleRouter和UIRouter。这部分是公共基础设施,各端都要集成。
左侧是构建系统,它不在组件化代码中,属于辅助系统,负责组件和各端应用包的构建。
====================================================================
组件化实践中比较核心的两个技术点是,组件间交互和组件间路由。
组件间交互的难点是降低组件耦合度,最好能达到完全无侵入式的调用。经过调研,iOS端使用ModuleManager的方式,它被定义为最底层的服务组件,每个组件都需要对外提供被调用的服务接口,接口的定义存在于ModuleManager组件。ModuleManager的代码对其他组件代码来说是无侵入的,只负责对传递过来的数据进行解析,并将调用消息传递给对应组件。
为了解决URL硬编码 ,以及字典参数类型不明确等问题,iOS端在组件化方案中选用了Protocol方案,在程序开始运行时将自身的Class注册到ModuleManager中,并将Protocol反射为字符串当做key,Class遵守协议并实现协议定义的方法,外界通过Protocol获取的Class并实例化为对象,调用服务方实现的协议方法。独立APP和各个插件的服务注册的时机不同,独立APP是在程序启动时,而插件则是外部调用插件时,在插件退出时去需要解除注册释放资源。Protocol方案描述如下:
在Android端,组件间交互使用的是ZRouter组件,实现思路和iOS端类似,是参考了java中SPI机制(服务提供发现机制),每个组件对外提供一个服务接口service,接口的实现交给对应组件内。在组件初始化注册时候,会同时注册该service接口和对应service实现。业务方使用时,只需要通过service接口调用组件功能。这样组件间就没有了直接依赖关系,实现了组件间解耦隔离。具体调用如下图所示:
组件间路由跳转方面,iOS端采用了注册URL的方式,注册的时机分为静态、动态和懒加载三种,懒加载方式即为在调用跳转方法时检查URL与ClassName是否已经注册绑定,如果未绑定则从模块静态信息表中获取并完成注册绑定,Handler可以在动态注册时进行指定,这样跳转逻辑即可实现完全自定义而不走底层的统一跳转逻辑,同样要注意的是插件端需要在退出插件时释放资源并取消注册。
Android端针对组件间UI跳转的实现方面,虽然前面讲到的ZRouter也能做到Activity、Fragment、View之间跳转,但是代码实现过于复杂。所以我们借鉴了业内组件化的优秀思想,专门开发了一个用于组件间UI跳转的UIRouter。在编译期间,通过Activity上添加的@RouterPath注解,生成一张Key为Scheme或页面短码,Value为Activity的路由表。跳转任何一个Activity都交由路由框架,根据路由表决定启动哪个Activity。
为了提升开发效率,减少UIRouter初始化时重复开发的代码,我们开发了一个插入自动注册代码的gradle插件,利用此插件在编译期通过ASM向指定方法中注入初始化代码。
同时,在组件库注册的时候也有用到这个技术;组件初始化类在debug模式下通过反射加入内存,在release模式下则通过ASM插入注册代码。这样在debug模式下可以缩短编译时间提升开发效率,在release正式包中运行时可减少反射带来的消耗。
整个优化流程如下:
==================================================================
有了层次清晰的组件划分,那么如何快速构建组件和项目成了必需要解决的事情。针对组件化,爱奇艺知识团队结合公司已有的构建系统,开发了一套适用于组件化的快速构建子系统。
为了解决多端共用一套代码和在各个插件端都有包大小的限制的前提下,在组件库中存在的差异代码通过宏分割来控制,实现差异代码隔离,编译时仅编译当前指定的某一端代码,打包时通过指定打包参数来设置宏配置,完成指定端的构建。
iOS端每个组件都是一个单独的工程,由不同的git私有仓库来管理,各个组件是在主项目中通过CocoaPods来集成,将所有组件当做二方库集成到主项目中。爱奇艺知识APP与各端插件虽然都采用了Cocoapods集成的方案,但是在版本依赖上有所差异,为提升开发效率,知识APP作为独立应用程序直接采用了指定git仓库tag号的方式来依赖组件库,插件则需要通过插件库的podsec设置依赖来集成组件库的,这就需要将组件库打成二进制的库文件上传到云,并上传组件库的podspec到私有库中。iOS插件端在主项目中集成组件主要分为两种方式分为源码和framework,在开发调试阶段采用源码方式,可以直接修改代码完成需求开发,在打包提测和发布时采用生成framework,可以加快编译速度不会对外暴露源码。
iOS端选择Jenkins作为构建系统,在组件化初始阶段,我们组件的构建是通过先构建最基础的组件,然后再构建上层组件来完成的整体构建,随着组件库数量增多,依赖关系变复杂之后手动逐一触发构建成为了构建过程的痛点,于是开始进行构建优化,引入了Jenkins的ParameterizedTrigger插件并配合shell脚本使用,使得我们支持组件的单个构建的同时,在主项目构建时支持触发多个组件,组件单独构建时也支持配置依赖构建的项目,实现了一次触发完成全部组件的构建。
组件库构建时会对当前迭代分支的代码进行更新检查,如果存在更新则会构建组件库,不存在更新则直接跳过此次构建。随着端的增加构建系统支持了多端构建,iPhone插件和iPad插件为不同的插件Job,通过脚本实现端的区分完成构建。建系统还实现了版本自增和定时构建,每一次构建完成后都会更新podspec文件中的版本号,在下一次构建时如果未手动指定构建版本便会获取之前的版本进行加一实现版本自增。构建系统对接了企业内部的即时通讯工具,在构建完成后发送通知给已经订阅的用户。下图描述了组件构建流程:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
![](https://i-blog.csdnimg.cn/blog_migrate/b7c4a1bde46d78b25bd6b0c79c004773.jpeg)
最后
分享一份NDK基础开发资料
分享内容包括不限于高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
]
分享内容包括不限于高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!