淘系技术部定义Bundle
署名2021-02-25

组件化的诞生与定义Bundle

淘系技术部为了应对之前讲的挑战和隐患请点击查看相关内容手机淘宝内部淘系技术部发起了对大型APP的重构计划,淘系技术部需要这样一个框架,其应该满足如下条件。

支持大量丰富业务的接入,同时业务之间能够保持清晰的边界,淘系技术部各自可以继续灵活迭代。

用一批统一的中间件支撑起各种业务的底层功能,保持中间件代码的全面复用。

能够尽量保持对系统的低侵入,遵循原生运行机制以降低后期的维护成本。

用户设备应尽量体现一个简单客户端的特性,同时特定的业务功能应按需获取,保持体积的可控性。

基于组件化的思想,淘系技术部定义了业务Bundle的概念,可以将其简单地理解为一个独立的业务模块,格式与官方的module格式基本相似,每个Bundle都可以有自己的依赖库,在工程期,Bundle会被打包进APP,在运行期,会被Atlas容器加载运行,淘系技术部实现与其他业务隔离和可独立插拔的效果。

Bundle间通信能力

Bundle 间通信图示如图所示。

淘2.png

     Bundle 间通信能力

(1)UI总线

Bundle间通过显示启动的Activity通常需要直接引用到另一个bundle的Activity class,这样bundle间就会代码耦合严重,通过导航、ARouter、auto-register等组件可以实现UI解耦,以及跳转逻辑和系统实现的分离,从而避免Activity改名导致的大量修改。

(2)消息总线

所有的message(消息单元)都将通过Messenger进行发送,通过注册事件与反注册事件来完成消息传递,类似一个轻量的Eventbus,避免了业务方出现BroadcastReceiver不注销而导致内存泄漏等异常情况的产生。

(3)服务总线

Bundle通过Service的形式对外提供服务,避免用户使用AIDL等底层繁杂实现,Bundle间只需要通过服务总线Services.get获取并调用服务,其中,所有Bundle提供的Service AIDL都会在公共库中进行维护,淘系技术部的每个Bundle自身将维护3个模块,分别是业务逻辑、服务实现和接口。

业务Bundle

淘系技术部推荐业务Bundle上层使用Android Jetpack组件,以及MVP(Model-View-Presenter)等模式开发淘系技术部自己的代码,官方Jetpack组件可以实现业务逻辑与UI的深层解耦合,通过数据驱动UI来实现逻辑分层,具体说明如下。

UI Controller层包含Activity和Fragment;其次是ViewModel层,既可以做MVVM(Model-View-ViewModel)中的VM、MVP中的P,也可以做UI中的数据适配,层可以实现数据驱动UI;最后是Repository层,它作为SSOC(唯一真相源),是一个外观(Facade)模式,对上层屏蔽了数据的来源,数据可以来自本地(local),也可以来自远程(remote),数据持久化策略向上透明。

其他方式

当然,开发者也可以通过官方serviceLoader、serviceHub等形式,来统一管理自己的Service实现以及接口对应关系,这些都是淘系技术部推荐的做法。

淘系技术部不建议业务Bundle有直接的资源依赖,如果是2个或者更多的Bundle依赖同一个资源,或者依赖同一个基础依赖库,那么更好的做法是将该资源下沉到base.apk中,业务Bundle将通过compileOnly的形式来依赖该资源,最终这个资源也会被仲裁到base.apk中。

最终淘系技术部的实现如图所示。

淘3.png

业务Bundle实现原理图