我希望阅读本篇博客的童鞋都是有一定的 Android
基础的,并且近期想实施组件化方案的.希望这篇文章能帮助到你,让你知道什么是组件化,有哪些可选的方案
下面这幅图相信大家平常多多少少都能看见类似的.
基础组件层
, 包括但不止以下方面SP
存储Theme
Style
Color
Dimen
Drawable
业务模块
每一个 业务模块
彼此之间是没有任务的关系,彼此的代码和资源都是隔离的,并且不能够相互引用,每一个都是平行的关系.
而组件化最关键的几点核心就是:
单独运行
的能力业务模块
打包出一个全新的 Apk
以上的三点就是 Android
的组件化,用一句话来解释就是:
Android 组件化就是利用多个
Module
来表示应用的多个模块实现代码和资源的隔离,并且每个Module
都有单独运行和组合的能力.
实现上述的几点并不难,难点是如何在组件化之后,我们的代码还能像以前一样跳转和使用其他业务模块的功能
所以如何当你项目打算组件化了,你就要解决组件化之后会带来的两个核心问题
凡是解决了上面两个核心问题的方案都可称之为组件化方案.所以组件化方案到底解决了什么问题,每一个开发人都应该心里有一个数,而不是跟风使用组件化方案都不知道到底解决了什么问题,也不知道为什么要组件化.
因为每一个 业务模块
都是互相独立没有丝毫的关系的,所以以前的跳转方式和功能的调用都不管用了.比如以前的跳转
Intent intent = new Intent(this,XXX.class);
startActivity(intent);
因为上述代码明确指定了 XXX.class
为目标 Activity
,而组件化了之后你要跳转的 Activity
很可能是其他业务模块的,你是引用不到的,这时候你是没办法跳转过去的,那么如何去解决呢?
解决方案如下:
以上两种都是系统支持的方式,你完全可以采用这种方式去解决跳转的问题
每一个业务模块本质上是一个 Lib
,被壳工程包含这个模块的功能就在 Apk
当中了.
但是每一个 业务模块
的功能很可能需要被其他模块使用,而每一个 业务模块
又是代码和资源的隔离的.所以要实现 A 业务模块
的功能能被其他 业务模块
调用,那么 A 业务模块
就需要通过一定的方式供别的 业务模块
调用.
可以有的做法有:
这一步的实现明显比跳转的难度更难.所以为什么会有各种各样的组件化的方案的诞生,他们就是帮助开发者解决这个问题的.
如果你自己去解决这些问题,你的代码会写的很恶心,如果你能解决这些问题并且代码还能写的很优雅,那么恭喜你,你也写了一个组件化方案
这里稍微说一下如何实现服务发现这种思路的功能
假设你的业务模块被加载和卸载会有一个类似于 生命周期
的概念,大白话就是壳功能加载和卸载 A 业务模块
, A 业务模块
都能知道
那么我们可以利用下面几步实现服务发现:
基础业务模块
基础业务模块
中放置一个 Map
, key
为 Class
, value
为 T
.put
到 map
集合中map
集合中 remove
基础业务模块
是指每一个业务模块都会依赖的一个 业务模块
,虽然它叫业务模块,但是它内部不写具体的业务代码,而是为每一个 业务模块
提供一些基础公用的代码或者资源
上面的方式就可以解决这个问题,但是这里分享的只是解决这个问题的思路,我们还有一个前提条件要能被通知到业务模块被加载和卸载.
当你业务模块被加载的时候,我上面一直在说这句话,其实模块的情况下, A 业务模块
被壳工程依赖,当运行的时候其实 A 业务模块
模块并不知道自己的状态.只是代码被包含到 Apk
了而已.
此时虽然壳工程依赖了 A,B,C 三个 业务模块
,但是当程序启动的时候,他们都不知道自己被依赖使用了,所以这里缺少一个所谓的通知,实现的方式不考虑维护性的话也有很多:
业务模块
都写一个广播,在壳工程加载的时候能被通知到业务模块
都写一个 Activity
,在壳工程加载某一个模块的时候,利用上面的跳转解决方案通知业务模块
都在指定的包下创建一个特别的类,统一实现了某接口,在壳工程加载模块的时候,能反射到该类实现一个通知正因为上面的两个原因阻挡了你组件化的进程,而上面两个核心问题你自己去解决不仅麻烦,而且不够通用,所以很多组件化方案应运而生.他们不管做的有多好,最根本的就是解决了上述的两个问题.每一个组件化方案都是如此.
以上的都是可用的一些方案,都从根本上解决了上述两个问题,并且每一个框架都有各自的优点和缺点.
上述的所有方案从性质上来分分为两类:
URI
的Action
的什么意思呢?
基于 URI
的就是框架的路由模块设计的核心是围绕 URI
设计的,天然的和 URL
等完美的结合.让一个 URI
和一个目标界面产生 1-1 的关系,给框架一个 URI
就可以路由到一个目标界面
基于 Action
的就是所有的操作都是用 Action
表示,至于你用 Action
去做什么,完全由你自己去实现,框架帮你做的就是在任何一个地方发起的一个 Action
,都能通知到对应模块,让指定模块去处理这个 Action
.
除了 CC
的其他方案都是基于 URI
设计的, CC
是基于 Action
设计的.两者并没有所谓的谁好谁坏,都已经解决了上述的两个核心问题.但是站在我的角度上看, Android 组件化
采用基于 URI
设计的方案会更好一些.毕竟 URI
是更加通用的一个协议,大家都对这个概念是有的,而且比较容易接受.虽然 CC
的 Action
也可以充当 URI
的 Path
,但是毕竟基于 URI
的还支持 Query
(即?后面的键值对) 的使用, 路由方面是肯定比不上基于 URI
的
回顾组件化带来的两个核心问题:
跳转方面,基于 URI
的明显会更好,这点是毋庸置疑的
调用任意模块的功能个人觉得通过服务发现的方式也会更好,因为接口调用都是显示调用的,方便后续的维护
选择方案的时候不仅仅要考虑框架提供的表面功能,一定要考虑维护性,我的建议很简单,一个框架应该尽可能的向以下几个方面靠拢
IDEA Plugin
去帮助你把 跳转的地方和目标界面 联系在一起,达到一个 "显示" 调用
当然还有我没有想到的,有兴趣的可以留言.以上的框架中我推荐使用
Component,它是基于 URI
设计的,并且比其他的基于 URI
设计的功能更全,更完善,也更好用.欢迎大家使用