前情提要
传统的开发模式是全部的都在app模块里面,项目越做越大,单一模块的开发,耦合非常严重。那么项目组件化、模块化就应运而生了。
项目组件化
说到项目组件化,大家应该都不陌生,下面说一说我理解的项目组件化:意思是把项目的功能分成一个个单一的功能组件,然后进行组装成一个完整的项目。
组件:指的是单一的功能组件,如视频组件(VideoSDK)、支付组件(PaySDK)、路由组件(Router)等,每个组件都能单独抽出来制作成SDK。
而现在说的组件化,还有个模块化,这也顺带说下模块化是什么?
模块:指的是独立的业务模块,如直播模块(LiveModule)、首页模块(HomeModule)等。模块相对于组件来说粒度更大,模块可能包含多种 不同的组件。
组件化开发的好处
1.避免重复造轮子,可以节省开发和维护的成本。
2.可以通过组件和模块以业务基准合理地安排人力,提高开发效率。
3.不同的项目可以共用一个组件或模块,确保整体技术方案的统一性。
4.为未来插件化共用同一套底层模型做准备。
模块化开发的好处
1.业务模块解耦,业务移植更加简单
2.多团队根据业务内容进行并行开发和测试
3.单个业务可以单独编译打包,加快编译速度
4.多个App共用模块,降低了研发和维护成本。
组件化和模块化的本质思想是一样的,都是为了代码重用和业务解耦。区别在于模块化是业务导向,组件化是功能导向。
项目体积越来越大后,必定会有超过方法数65535的一天,要么选择MultiDex的方式分包解决,要么使用插件化的方式来完成项目。
组件化和模块化的划分将更好地为项目插件化开路。
组件化架构就是文件层级上有效地控制沟通和个体独立性的做法。
怎么样的组件化算合格?
Android Studio以依赖的方式给每个module之间提供了沟通和交流的渠道,从而形成聚合。
如果一个个体和非常多的个体交流,则使用依赖关系。一个个体为非常多的模块提供服务,这样效率是很高的,而且通信成本很低。
假如有一天,这个个体出逃了,或者上司生气了,说以后都不需要这个个体了,要移除这个个体和其他人的关系,后果将是灾难性的,其他一推人会跟你抱怨:“他为我们做了太多的事情,离开他我们找不到其他人做事了”。
所以作为这个运行系统的设计者和统筹者,我们应该设计一个为移除或者替换某个个体的行为付出最少代价的方案。
组件化开发要注意的几个点
1.要注意包名和资源文件命名冲突问题
2.Gradle中的版本号的统一管理
3.组件在Application和Library之间如何做到随意切换
4.AndroidManifest.xml文件的区分
组件间通信
组件间是互相独立的,它们并不存在任何依赖。没有依赖,就无法产生关系;没有关系,就无法传递任何的的信息。这个时候就需要第三方的协助--基础层。基础层就是跨越组件化层级的关键,也是模块间信息交流的基础,组件层的模块都依赖于基础层,从而产生第三者联系。
Android中的Activity、Fragment、Service信息传递相对复杂,一开始考虑使用广播的方式去实现信息传递。但是系统系别的广播其传递是耗时的,而且可能被捕获(不安全)。工程师开发了更节省资源、更高效的工具,这类工具就是事件总线机制,推荐框架:EventBus、RxBus、ModuleBus、ModularizationArchitecture
组件间跳转
在组件化中,两个功能模块是不存在直接依赖的,其依赖规则是通过Base module间接依赖的,那么组件间进行跳转时,原始跳转不可以直接显式跳转,只能进行隐式跳转的方式。
隐式跳转时需要进行验证是否会接收Intent,需要对Intent对象调用resolveActivity(),如果结果为非空,则至少有一个应用能够处理该Intent,且可以安全调用startActivity();如果结果为空,则不应使用该Intent。
隐式跳转是原生的,它和广播一样,范围是整个Android系统都能收到。是否有更加好的跳转方式来完成页面跳转呢?
ARouter、ActivityRouter、天猫统跳协议、DeepLinkDispatch、OkDeepLink
组件化打包需要注意的
资源冲突
1.AndroidMainfest冲突
2.依赖包冲突
3.资源名冲突
组件化混淆
每个module在创建之后,都会自带一个proguard-rule.pro的自定义混淆文件。每个module也可以有自己混淆的规则。
但在组件化中,如果每个module都使用自身混淆,则会出现重复混淆的现象,造成查询不到资源文件的问题。
解决这个问题的关键是,需要保证在apk生成的时候有且只有一次混淆。
最简单也是最直观的方法: 只在Application module中设置混淆,其他module都关闭混淆。
第二种方法: 将Library module 自身拥有的proguard-rule.pro文件打包到aar中的设置,当Application module将全部的代码汇总混淆的时候,Library module会被打包为release aar,然后被引用汇总,通过proguard.txt规则各自混淆,保证只混淆一次。
添加一个属性到Library module 的build.gradle文件中:
defaultConfig{
consumerProguardFiles ‘proguard-rules.pro’
}
完~