可以看到整个大风车的主工程可以分为四层:
所以你可以看到这个工程与模块之间、模块与模块之间的依赖关系真的是美如画,相互引用导致扩展性和可维护性都很差,而且难以测试。我们来看看这种项目架构的问题在哪里:
我们先来看一看重构后的架构,如下所示:
重构后的大风车采用多容器架构,我们来看看这套架构是如何实现的。
既然要把业务模块化,那就要有承载模块的容器,目前来说主要用以下三种容器:
注:手淘提供了细粒度的View容器方案:Virtualview-Android,它可以通过下发XML配置文件,动态的渲染View。
从长远来看,这三套容器都不是用来相互取代对方,而是会长期并存,取长补短,相互助益。
那如何实现这三套容器呢?
这三套容器的实现,我们后续都有详细的文章来讨论,我们接着来看看模块架构的实现。
一个良好的系统设计纵向分层,横向模块化。我们来看看从纵向和横向的角度如何去设计一个模块。
一般说来,从纵向角度,一个模块一般可以划分为三个部分:
一个模块就这样可以被划分为三层,如果是更加复杂的模块,我们还有做好层与层间的解耦与通信,我们接着来看一下横向架构如何实现。
横向架构就是如何去处理视图、数据与业务逻辑的关系,关于这一块内容的实践,从最初的MVC、到MVP、MVVM,各种架构的目的都都是希望模块的耦合性更低、独立性更强,移植性更好。
Google自己也开了一个Repo来讨论这些框架的最佳实践,如下所示:
Google官方也提供了MVP的实现,这个MVP框架的核心思想如下所示:
官方的这套框架存在两个问题:
总的说来,就是当业务量急剧膨胀的时候,就会需要写大量的View接口和Presenter类,而且这还牵扯到Presenter类与Activity生命周期同步的问题,在大型项目面前,这些操作都会变得十分复杂。
综上所述,一个理想的方案就是结合ViewModel组件与LiveData组件来实现MVVM框架。
这套框架有两个重要的原则:
注:这里可能有人有疑问,非得用Lifecycle组件吗,利用View的onAttachToWindow()、onDetachToWindow()这些方法来模拟Activity或者Fragment的生命周期不可以吗,事实上View的生命周期在 一些特殊的场景下是不可靠的,例如:RecyclerView、ViewPager,所以我们还是需要利用Lifecycle组件来监听Activity或者Fragment的生命周期变化。
解决了模块间的解耦问题,另一个就是模块间的通信问题。在一个大型的应用里很多模块都是可以独立运行甚至独立成一个App的,这就牵扯到模块间的数据交互和通信问题,例如:最常见的一种 场景就是子模块需要知道主应用里的登录信息等等,模块间的通信业可以分为两种情况:
进程内通信的手段有很多种,最常见的就是EventBus,
EventBus 用来完成 Activities, Fragments, Threads, Services 之间的数据交互和通信。
EventBus是早期页面通信和模块通信常见的手段,它的好处是显而易见的,将事件的发布者与订阅者解耦,无需再定义一堆复杂的回调接口,但是随着工程的 膨胀,它的问题也凸显出来,具体说来:
但是即便这样,EventBus还是一个优秀的进程内通信的方式。
注:当然除了EventBus以外,在简单的通信场景下,我们还可以选择LocalBroadcastReceiver。LocalBroadcastReceiver是一个应用内的局域广播,它也是利用一个Looper Handler维护一个 全局Map进行应用内部通信,与EventBus不同,它发送的是字符串。LocalBroadcastReceiver在面临业务膨胀的时候,也会遇到消息字符串的管理问题。
跨进程通信可以借助Content Provider来完成,
Content Provider 底层采用的是Binder机制,用来完成进程间的数据交互和通信。
模块通信采用Content Provider的方式来解决,一个比较常见的场景就是多模块共享登录信息,登录信息可以用Content Provider来保存,当登录状态发生变化时,可以通知到 各个模块。
通过上面的分析,我们已经完成了一个设计良好的模块,但是模块的接入仍然面临着诸多问题,例如:如何界定模块的生命周期,用户信息等如何同步,模块如何进行注册以及初始化 等问题。少量的模块,这些都不是问题,但是当模块增长到一定的数量级的时候,这个问题就会变得十分突出。
模块生命周期的生命周期可以做如下划分:
模块的初始化一般在Application里进行,当然也有懒加载的模块,模块的初始化一般传递应用上下文信息,用户信息,配置参数等信息,这里可以考虑对模块进行自动初始化,具体 流程如下所示:
模块化拆分不是一个简单的事情,没法一蹴而就,也不可能让团队全部停下来去做拆分重构,所以真正实施模块化需要按照以下几个步骤循序渐进的进行。
技术上的重构并不能带来短期上的收益,它是一个长时间才能显现好处的事情,你往往花费了很多时间来做这些事情,它也非常的有意义,但是老板看不到,业务上也不会带来明显的增长。所以 第一件事情,就是做好团队成员的思想工作。
事实上,大部分研发同学都还是非常有技术追求的,但是我们工程通常有很多历史遗留问题,也就是所谓的技术债,要去重构这些东西,成本是非常高的,面对这种情况在加上平时业务需求多,时间紧,大家 通常都会想:
重构难度这么大,出了问题怎么办,算了,别人怎么写,我也怎么写好了。
这是一个很普遍的现象,这种情况下就需要有一个有魄力的leader打响第一枪,有了第一个阶段的重构,大家看到了曙光,就会开始陆续吐槽原来的设计有多么烂,应该如何设计等等。
相信大多数从事Android开发的朋友们越来越发现,找工作越来越难了,面试的要求越来越高了
除了基础扎实的java知识,数据结构算法,设计模式还要求会底层源码,NDK技术,性能调优,还有会些小程序和跨平台,比如说flutter,以思维脑图的方式展示在下图;
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
调优,还有会些小程序和跨平台,比如说flutter,以思维脑图的方式展示在下图;
[外链图片转存中…(img-mIKq99OB-1714758906196)]
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!