Android模块解耦之组件化
引言:在移动开发中,我想大部分开发人员都会面临一个问题,随着项目的开发与不断的迭代,业务也会随之不断壮大,也就意味着业务模块越来越多,这个时候就会出现一个问题,各个模块之间的相互引用,导致模块之间的耦合越来越严重,最终迭代会牵一发而动全身,项目的迭代和维护都特别困难;一些门户型的APP还伴随着子应用单独包装推广,影子应用单独发布等等需求,那么一个合适的应用框架的需求是必不可少的,那么这篇文章就通过组件化来分析Android模块解耦的实现,实现多人真正的协同开发,每一个模块实现单独的版本控制、单独编译、单独运行;
一、组件化概述
组件化开发就是将一个APP分成多个模块,每个模块我们都可以看成是一个组件,也就是在IDE中所创建的(Module),在开发的过程中我们可以对这些组件进行单独调试,编译和运行以及进行单独的版本控制等,但是最终发布的时候是将这些组件合并统一成一个apk,这就是组件化开发。
二、组件化的优势
1.提升编译速度
做Android开发人员都知道,在项目达到一定的规模的时候,编译是一件十分痛苦的事情,短则几分钟,长则十几分钟。我们在修改了很小一块代码就要去编译整个项目,这样会导致开发效率降低;那么由于通过组件化我们可以实现单独编译,就会极大的改善这个问题;
2.适应并行开发
通过组件化可以更好的去适应并行开发,因为我们可以为每一个模块进行单独的版本控制,甚至每一个模块的负责人可以选择自己的设计架构而不影响其他模块的开发,与此同时组件化还可以避免模块之间的交叉依赖,每一个模块的开发人员可以对自己的模块进行独立测试,独立编译和运行,甚至可以实现单独的部署。从而极大的提高了并行开发效率。
三、组件化与插件化的区别
近几年插件化与热修复可谓是十分火热的话题,其实部分开发者对组件化与插件化区分并不明确,特别是热修复与插件化之间的关系;所谓插件化就是将整个APP拆分成很多模块,这些模块包括一个宿主和多个插件,每个模块都是一个APK(而组件化的每个模块在打包为一个APK的时候是个Lib,在开发过程中我们可以设置当前的Lib为Application来实现单独运行编译),最终打包的时候将宿主APK和插件APK分开或者联合打包。而热修复是动态修复线上项目的BUG,而不用重新发布版本,达到快速修复BUG的目的,其实我们可以看做是插件化的一个分支,它们底层运用到的技术都是差不多,通过DexClassLoader来实现动态加载,也有一些其他的方案,比如说从native层hook来实现方法的替换,但是这种方式限制比较大;
四、组件化的具体实现注意点
4.1第三方库依赖冲突和依赖统一管理
在组件化的具体实施过程中,我们创建的每一个module都有可能会去依赖相同的一些第三方库,例如jar,aar等文件,那么在运行的时期就会可能报错而导致无法运行,针对这个问题有以下几种方式可以解决:
1.创建commonSDK这样一个module,在module里面可以用来放置我们每一个module都会用到的工具类和一些基类,然后让每一个module都依赖这个commonSDK的module,整个项目所有的第三方依赖库都可以直接写在commonSDK的配置文件build.gradle当中即可,这样就可以实现依赖的统一管理,而且解决了module之间“部分”的重复依赖的问题,如图4-1所示;
2.上面为什么说只解决了部分依赖的问题呢,因为有一些第三方的库,例如dagger2依赖注入,阿里的路由ARouter需要在编译时期注入代码生成对应的类,那么这个时候就必须要将对应的依赖放入到每一个使用到这个库的module中去,如图4-2,那么此时就存在一个第三方库版本统一的问题,为了实现不同module版本的统一管理,我们可以在项目的根目录下面创建一个config.gradle,子模块直接引用对应的版本号即可,修改的时候就可以实现统一修改,而不用每一个子module都去修改了,如图4-2,图4-3;
4.2资源冲突的解决
同样的多个module之间也可能存在资源文件冲突的问题,那么这个时候只需要在每一个子模块的build.gradle中加上对应的资源文件标识符resourcePrefix即可,如图4-4
4.3Module单独编译和打包编译的设置
我们使用组件化的架构,在实际的开发过程中每一个模块是可以单独编译运行的,那么这个时候对应的配置文件,Application的调用都会有所不同,所以这个时候就需要进行一些设置,主要的设置步骤如下:
1.在主项目根目录下的gradle.properties中设置一个boolean值的标志,通过改变标志位的boolean取值,来判断当前的module是编译成lib还是Application,配置如图4-5:
2.依赖的设置,由于有部分的类需要在每个子模块下面进行依赖,为了解决重复依赖,需要根据标志符采用不同的引入方式,如图4-6:
3.配置文件的设置,我们的四大组件等等都需要在AndroidManifest中进行配置,那么子模块在不同状态的时候也需要进行不同的配置,所以这个时候需要在main文件夹下面分别创建一个debug和release文件来分别存放子模块编译为不同状态时所依赖的配置文件,如图4-7所示:
4.4如何实现模块之间组件的通信
组件当中,实现模块之间的通信是最重要的问题了,其实采用隐式意图可以启动不同组件之间的一些Activity,Service等,可以用来实现组件化模块之间的通信,但是不方便扩展和统一管理,同时也会导致配置文件比较混乱,这个时候我们就可以通过路由机制来实现模块之间的通信,目前已经有对应的开源项目,例如阿里的ARouter就是用来实现组件化模块间互相通信的一个开源项目,它支持直接解析URL进行跳转、参数按类型解析到Bundle,支持Java基本的数据类型,那么具体的实现方式可以参照github上面的说明文档来进行实现,其实相似的开源项目还是比较多的,我们也可以根据自己公司的需求来实现自己的路由;
五、总结
本文涉及到组件化的具体实施过程,以及在使用过程遇到问题的解决方式。主要涉及到配置文件的一些设置和依赖冲突,依赖统一管理的解决,以及采用ARouter来实现组件间的URL跳转等等,由于篇幅原因,本文并未讲解路由的具体实现原理,那么下一篇文章我将给大家来讲解如何来实现一个路由,达到组件之间的通信;