今天给大家分享的是英语流利说Android端的代码架构的演进,标题挺高大上的,其实也并非多高大上的东西,整个演进过程,也是借鉴了业界很多大型应用在架构上的沉淀以及思想,可能有些东西还有点老生常谈,不过我们保证尽量都是干货。
英语流利说的架构一直在迭代调整。年中旬启动了一次较大规模的重构,经历了简单的半个小时会议,大家一致支持,开启了英语流利说这次的架构演进之路??
这是当时的Task,也是今天我们入手介绍的主要内容:
I.英语流利说早期架构应该有很多小型项目,在快速迭代中也存在着这样的架构,如果你们正想往中大型项目看齐,那么可能这篇文章会是你有效的解决方案之一。
英语流利说Android端早期的架构,主要以内部广播方式进行必要的解耦,随着不断的迭代,虽然基本的核心公用代码根据特性已经衍生出了A、B、CModule,但是上层业务复杂度不断增加,各模块相互耦合越发严重,虽然一直都有在架构上做一些小的调整,但都无法根治问题,以此维护性的问题便逐渐凸现。
II.英语流利说核心架构这套架构的核心思想Plugin模式是借鉴了国内公认最优秀的Android项目所采用的架构1,在保留架构核心思想的基础上,以尽量轻,尽量简单的原则做了一些减法以及调整。除了核心架构,我们也做了很多辅助架构为了支撑整套架构灵活性、轻便性。
如上图,整个项目清晰的被拆分为三个层级:基础层、功能模块层、App模块(Application层),其中功能模块层中的各个功能模块是我们需要解耦出来的,而基础层的每个模块遵循单向依赖关系:从距离功能模块层最近的中央控制的center模块、再往下的负责全局监控的monitor模块、公共布局相关的ui模块、公共网络数据相关的net模块、公共底层工具的sdk模块直到最基本的为国际化做准备的language模块、供引入第三方库并二次封装的support模块。
1.核心架构说明整体特性这套架构最明显的特征就是对功能模块层中的每个模块进行了解耦,如下图,使得App模块可以轻易的取消对任何功能模块的依赖而不影响编译与使用,因此我们也将其称为Plugin模式。
核心功能思想:这套架构是就对各功能模块解耦展开的,而解耦就如A与B需要解耦,引入C,让A、B都依赖C。关系如上图,我们需要对A、B模块解耦,让A、B模块都依赖中央控制center模块(下文简称中控模块),并且在中控模块中定义A、B模块需要对外开放的接口,在A、B模块中实现各自的接口,然后在App模块中通过反射将A、B模块中的实现传入中控模块,这样App模块、A模块、B模块都可以通过中控进行对各个功能模块进行访问,而当App模块没有依赖A模块时,中控模块会返回在中控模块实现的一个EmptyAPlugin,至此完成整个环路。
2.引入多进程层在基础层中嵌入多进程层,主要是由于在Android中内存共享每个JVM是独立的,在架构层面让所有的各自非UI进程的数据结构都是PackageVisible,防止被非当前进程调用。
模块命名前缀为lls_process是进程模块,并且每个模块的区分以进程为单位
1.多进程的原因其实在后来的演进中,我们为了减少因为进程调度对手机资源(CPU、I/O)的消耗,尽可能的合并以及缩减了各类进程(保持一个常驻进程、多个以生命周期为界限的短生命周期非常驻进程)。多进程化当时有受到了业界某大型安全应用在InfoQ上的一个关于大型移动应用开发的演讲2的启发,他们谈到了在一些特定场景下的优势,以及他们从之前的6个进程演变为17个进程,从而使得应用变得更加的稳定。
与其说原因,不如说是谈谈适用的场景:
提高UI进程的稳定性以及各进程各自的稳定性。
独立组件充分解耦,充分独立。
为用户节约内存,更加灵活(如:只保留一个非主进程的来满足聊天的推送)。
减少引入部分第三方组件所带来的风险。
更有效的做UI进程的有损体验(如:打分进程CRASH以后,在用户使用过程中,通过重启打分进程重新录音打分的机制,尽量减少用户的体验损失)。
由于独立进程在自己的JVM上面,内存方面不会对UI进程的内存分配造成直接的影响,因此在一些内存占用较多如大图预览的时候,可以一次性使用,一次性回收。
2.多进程通讯架构这套架构是封装了非UI进程组件用于让非UI进程的Service快速集成并接受绑定Binder与UI进程的UIGuard组件进行IPC,如上图,基本原则就是:
UI进程只可通过UIGuard与另外一个进程的Service进行通信。
Service单向引用其所在进程的业务层,反向的信息流通过EventBus的形式流通。
UIGuard被UI进程的业务层单向引用,反向的信息流也是通过EventBus的形式流通。
Service业务层可通过Binder跨进程通信时对于非oneway的接口Block住当前线程等待接口回传的机制,再通过UIGuard转发透传Event从而实现直接向UI进程索要数据。
其实多进程架构我们已经通过我们的开源库lingochamp/FileDownloader3对外开源,不过为了FileDownloader独立进程与非独立进程的灵活切换,因此这套架构在FileDownloader上已经迭代为另外的版本,如果感兴趣可以看看早些的白癜风医院郑州哪家好白殿疯用醋