IBigerBiger的成长之路

Android组件化(一)-架构与配置

前几篇文章有介绍到插件化相关,确实插件化是一个充满黑科技的技术,对于插件化的开发者来说,需要对于Android的源码有很深的理解以及对于Hook技术有一定经验才可以进行下去,我之前几篇的关于插件化的文章就已经把我虐的不要不要的了,可以看出那些现在已经开源的插件化库的开发者本身的技术水平之强,以及付诸多少努力在于插件化这项努力上,而对于插件化的使用者来说,虽然享受着现在开源插件化库带来的便利性,但是难免会出现庞大的Android市场带来的各种个(keng)性(die)rom带来的乱七八糟问题,所以其实一般来说,如果可以避免使用插件化还是避免使用的。

那么怎么解决之前超级App面临的几项问题呢?

  • 65535方法数问题
  • 业务耦合,需要各业务协调,不利于敏捷开发
  • 编译过慢

那么不使用插件化的情况下就有人提出了关于组件化的开发,组件化开发就是将一个app分成多个模块,每个模块都是一个组件(Module),开发的过程中我们可以让这些组件相互依赖或者单独调试部分组件等,但是最终发布的时候是将这些组件合并统一成一个apk,这就是组件化开发。

关于插件化与组件化的区别用一张图就可以很明显的表示出来,如下


module_plug.png

项目架构发展流程

其实一个项目从开始到后期的成熟一般会经历如下的流程:

①.项目初期,耦合严重

对于比较早期的项目,无论从学习的角度还是从开发的角度,我们都习惯的将各个组件放入一个包里面,没有层级结构,业务、界面、逻辑都耦合在一起,在逻辑和功能都并不是很多的情况下是可以满足我们的开发需求的,一般架构如下:


架构1.png

在项目初期的情况下确实不会出现什么问题,可是随着开发人员的增多,业务功能的增多,就会发现面临找到一个功能相关的类会很麻烦,也会因为各种不相干人员对于不相干业务部分的修改而导致各种冲突,没办法,这样对于整个项目的开发来说是很没有效率的,只能面临重新架构的情况。

②.业务剥离

对于上面的问题,对于当时来说最好的解决方案就是将单一的业务模块放到一个包里面,由负责这个业务模块的人员进行开发以及后续的更新,这时候的架构图如下:

架构2.png

同样在当时的情况下,这样的架构是可行的,开发起来也美滋滋,但是随着后面的业务逻辑增多,业务之间的调用增多,就会出现如下的情况:

架构3.png

虽然上面的依赖关系举例有点太过于极端,但是真实场景中是存在的。各个业务某块之间耦合愈发严重,导致代码很难维护,更新,更别说写测试代码了。并且没办法彻底根治这个问题。这个架构做到最后,扩展性和可维护性都是很差,并且难以测试,所以这种架构模式在历史道路上面必然是会被抛弃的。我们必须面临重新架构。

③组件化

APP业务组件化架构整改的方向就是告别结构臃肿的时代,让各个业务变得相对独立。模块工程和类库工程之间遵循向下依赖关系,各个模块之间的遵循平级依赖关系。先看下整改后的各个独立业务模块与类库工程之间的向下依赖关系图:


构架4.png

这里通过一个MainModel提供统一的入口,每个业务独立的模块module共享项目的依赖库。由MainModel集成需要引入的业务模块,至于各个独立的业务模块之间的调用依赖关系,我们借助一个中间层充当路由功能,这个路由我们放在各个业务模块共同引用的依赖库那一层。由路由统一调度他们之间的依赖关系,路由调度解决平级依赖问题示意图:


架构5.png

通过路由统一调度,各个模块之间调用不再采用传统的显式调用,而是采用隐式调用的方式。从而使各个模块之间不再存在依赖关系。

至于路由Router是什么,以及这个调度相关的逻辑,在下一篇再做相关讲解。

组件化相关

通过上面的关于项目架构相关的发展流程,我们可以得出如下的结论

适合业务组件化的几种情况:

  • 业务较多、而且复杂

  • 业务之间的依赖需要解耦

  • 团队成员较多,需要各自开发相对独立的业务

APP业务组件化架构整改带来的好处:

  • 加快迭代速度,各个业务模块组件更加独立,不再因为业务耦合情况,在发版时候,由于互相等待而迟迟不能发布版本。

  • 稳定的公共模块采用依赖库方式,提供给各个业务线使用,减少重复开发和维护工作量。

  • 迭代频繁的业务模块采用组件方式,各业务线研发可以互不干扰、提升协作效率,并控制产品质量。

  • 为新业务随时集成提供了基础,所有业务可上可下,灵活多变。

  • 降低团队成员熟悉项目的成本,降低项目的维护难度。

  • 加快编译速度,提高开发效率

APP业务组件化架构需要解决的问题:

  • 资源冲突问题

    当分别开发模块时,容易出资源重复命名的问题,可以在build.gradle中设置

    1
    resourcePrefix "moduleX_"

    通过给模块设置不同的资源前缀,可以避免重复命名。

  • 跳转与调用问题

    这个上面也有说到是通过路由Router实现,在下一篇做详细讲解。

  • 多进程通讯问题

    多进程通讯主要是通过IPC来实现,对于这个通讯其实可以在路由Router中一起实现,怎么实现,在下一篇做详细讲解。

写在后面的话

本篇主要来分析项目架构发展流程,为何要实现业务组件化、组件化的方向、组件化的技术方案简单探讨、组件化带来的好处,由于目前个人对于组件化理解可能不够完善,以及现在组件化实施初期,很多观点有可能是错误的,很多技术坑还没涉及,后续会跟进更多相关实现方案。