Android组件化框架设计与实践,事件分发流程

问:组件化、模块化容易混淆,两者区别又是什么?

答:模块化就是将一个程序按照其功能做拆分,分成相互独立的模块,以便于每个模块只包含与其功能相关的内容,模块我们相对熟悉,比如登录功能可以是一个模块,搜索功能可以是一个模块等等。而组件化就是更关注可复用性,更注重关注点分离,如果从集合角度来看的话,可以说往往一个模块包含了一个或多个组件,或者说模块是一个容器,由组件组装而成。简单来说,组件化相比模块化粒度更小,两者的本质思想都是一致的,都是把大往小的方向拆分,都是为了复用和解耦,只不过模块化更加侧重于业务功能的划分,偏向于复用,组件化更加侧重于单一功能的内聚,偏向于解耦。

问:组件化能带来什么好处?

答:简单来说就是提高工作效率,解放生产力,好处如下:

  • 代码简洁,冗余量少,维护方便,易扩展新功能。

  • 提高编译速度,从而提高并行开发效率。

  • 避免模块之间的交叉依赖,做到低耦合、高内聚。

  • 引用的第三方库代码统一管理,避免版本统一,减少引入冗余库。

  • 定制项目可按需加载,组件之间可以灵活组建,快速生成不同类型的定制产品。

  • 制定相应的组件开发规范,可促成代码风格规范,写法统一。

  • 系统级的控制力度细化到组件级的控制力度,复杂系统构建变成组件构建。

  • 每个组件有自己独立的版本,可以独立编译、测试、打包和部署。

设计,构建组件化框架

回到刚开始讲的 APP 单一工程模式,看张常见 APP 单一工程模式架构图:

APP单一工程模式架构

上图是目前比较普遍使用的 Android APP 技术架构,往往是在一个界面中存在大量的业务逻辑,而业务逻辑中充斥着各种网络请求、数据操作等行为,整个项目中也没有模块的概念,只有简单的以业务逻辑划分的文件夹,并且业务之间也是直接相互调用、高度耦合在一起的。单一工程模型下的业务关系,总的来说就是:你中有我,我中有你,相互依赖,无法分离。如下图:

业务模块互相耦合

组件化的指导思想是:分而治之,并行开发,一切皆组件。要实现组件化,无论采用什么样的技术方式,需要考虑以下七个方面问题:

  1. 代码解耦。如何将一个庞大的工程分成有机的整体?

  2. 组件单独运行。因为每个组件都是高度内聚的,是一个完整的整体,如何让其单独运行和调试?

  3. 组件间通信。由于每个组件具体实现细节都互相不了解,但每个组件都需要给其他调用方提供服务,那么主项目与组件、组件与组件之间如何通信就变成关键?

  4. UI 跳转。UI 跳转指的是特殊的数据传递,跟组件间通信区别有什么不同?

  5. 组件生命周期。这里的生命周期指的是组件在应用中存在的时间,组件是否可以做到按需、动态使用、因此就会涉及到组件加载、卸载等管理问题。

  6. 集成调试。在开发阶段如何做到按需编译组件?一次调试中可能有一两个组件参与集成,这样编译时间就会大大降低,提高开发效率。

  7. 代码隔离。组件之间的交互如果还是直接引用的话,那么组件之间根本没有做到解耦,如何从根本上避免组件之间的直接引用,也就是如何从根本上杜绝耦合的产生?

组件化架构目标:告别结构臃肿,让各个业务变得相对独立,业务组件在组件模式下可以独立开发,而在集成模式下又可以变为 AAR 包集成到“ APP 壳工程”中,组成一个完整功能的 APP。

先给出框架设计图,然后再对这七个问题进行一一解答。

A组件化框架架构

从图中可以看到,业务组件之间是独立的,互相没有关联,这些业务组件在集成模式下是一个个 Library,被 APP 壳工程所依赖,组成一个具有完整业务功能的 APP 应用,但是在组件开发模式下,业务组件又变成了一个个 Application,它们可以独立开发和调试,由于在组件开发模式下,业务组件们的代码量相比于完整的项目差了很远,因此在运行时可以显著减少编译时间。

各个业务组件通信是通过路由转发,如图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NdemG3Lx-1615520318619)(https://upload-images.jianshu.io/upload_images/788498-2c26405226fd9ed8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]

这是组件化工程模型下的业务关系,业务之间将不再直接引用和依赖,而是通过“路由”这样一个中转站间接产生联系。

那么针对以上提出的七个问题,具体解决如下:

1,代码解耦问题

对已存在的项目进行模块拆分,模块分为两种类型,一种是功能组件模块,封装一些公共的方法服务等,作为依赖库对外提供,一种是业务组件模块,专门处理业务逻辑等功能,这些业务组件模块最终负责组装APP。

2,组件单独运行问题

通过 Gradle 脚本配置方式,进行不同环境切换。比如只需要把 Apply plugin: ‘com.android.library’ 切换成Apply plugin: ‘com.android.application’ 就可以,同时还需要在 AndroidManifest 清单文件上进行设置,因为一个单独调试需要有一个入口的 Activity。比如设置一个变量 isModule,标记当前是否需要单独调试,根据isModule 的取值,使用不同的 gradle 插件和 AndroidManifest 清单文件,甚至可以添加 Application 等 Java 文件,以便可以做一下初始化的操作。

3,组件间通信问题

通过接口+实现的结构进行组件间的通信。每个组件声明自己提供的服务 Service API,这些 Service 都是一些接口,组件负责将这些 Service 实现并注册到一个统一的路由 Router 中去,如果要使用某个组件的功能,只需要向Router 请求这个 Service 的实现,具体的实现细节我们全然不关心,只要能返回我们需要的结果就可以了。在组件化架构设计图中 Common 组件就包含了路由服务组件,里面包括了每个组件的路由入口和跳转。

4,UI 跳转问题

可以说 UI 跳转也是组件间通信的一种,但是属于比较特殊的数据传递。不过一般 UI 跳转基本都会单独处理,一般通过短链的方式来跳转到具体的 Activity。每个组件可以注册自己所能处理的短链的 Scheme 和 Host,并定义传输数据的格式,然后注册到统一的 UIRouter 中,UIRouter 通过 Scheme 和 Host 的匹配关系负责分发路由。但目前比较主流的做法是通过在每个 Activity 上添加注解,然后通过 APT 形成具体的逻辑代码。目前方式是引用阿里的 ARouter 框架,通过注解方式进行页面跳转。

5,组件生命周期问题

在架构图中的核心管理组件会定义一个组件生命周期接口,通过在每个组件设置一个配置文件,这个配置文件是通过使用注解方式在编译时自动生成,配置文件中指明具体实现组件生命周期接口的实现类,来完成组件一些需要初始化操作并且做到自动注册,暂时没有提供手动注册的方式。

6,集成调试问题

每个组件单独调试通过并不意味着集成在一起没有问题,因此在开发后期我们需要把几个组件机集成到一个 APP 里面去验证。由于经过前面几个步骤保证了组件之间的隔离,所以可以任意选择几个组件参与集成,这种按需索取的加载机制可以保证在集成调试中有很大的灵活性,并且可以加大的加快编译速度。需要注意的一点是,每个组件开发完成之后,需要把 isModule 设置为 true并同步,这样主项目就可以通过参数配置统一进行编译。

7,代码隔离问题

如果还是 compile project(xxx:xxx.aar) 来引入组件,我们就完全可以直接使用到其中的实现类,那么主项目和组件之间的耦合就没有消除,那之前针对接口编程就变得毫无意义。我们希望只在 assembleDebug 或者 assembleRelease 的时候把 AAR 引入进来,而在开发阶段,所有组件都是看不到的,这样就从根本上杜绝了引用实现类的问题。

目前做法是主项目只依赖 Common 的依赖库,业务组件通过路由服务依赖库按需进行查找,用反射方式进行组件加载,然后在主工程中调用组件服务,组件与组件之间调用则是通过接口+实现进行通信,后续规划通过自定义Gradle 插件,通过字节码自动插入组件的依赖进行编译打包,实现自动筛选 assembleDebug 或 assembleRelease 这两个编译命任务,只有属于包含这两个任务的命令才引入具体实现类,其他的则不引入。

代码,具体项目实践

一,创建工程

1,APP空壳工程

通过AndroidStudio创建一个APP空壳工程,如图:

APP空壳工程

然后在 APP 工程添加依赖具体业务组件 Module。比如:

依赖关系

2,具体业务组件Module

需要遵循一定组件命名规范,为何需要规范呢,因为需要通过组件命名规范来约束和保证组件的统一性和一致性,避免出现冲突。比如登陆组件,那么名称:b(类型)-ga(部门缩写)-login(组件名称),这就是我们基于共同的约定进行命名的,为后期维护和扩展都带来辨识度。

Login业务组件

二,业务组件配置文件

1,build.gradle配置文修改。如下:

if (isModule.toBoolean()) {

apply plugin: ‘com.android.application’

} else {

apply plugin: ‘com.android.library’

}

android {

compileSdkVersion rootProject.ext.compileSdkVersion

buildToolsVersion rootProject.ext.buildToolsVersion

defaultConfig {

minSdkVersion rootProject.ext.minSdkVersion

targetSdkVersion rootProject.ext.targetSdkVersion

if (isModule.toBoolean()) {

applicationId “com.hik.ga.business.login”

versionCode 1

versionName “1.0”

} else {

//ARouter

javaCompileOptions {

annotationProcessorOptions {

arguments = [ moduleName : project.getName() ]

}

}

}

}

sourceSets {

main {

if (isModule.toBoolean()) {

manifest.srcFile ‘src/main/module/AndroidManifest.xml’

} else {

manifest.srcFile ‘src/main/AndroidManifest.xml’

//集成开发模式下排除debug文件夹中的所有Java文件

java {

exclude ‘debug/**’

}

}

}

}

buildTypes {

release {

minifyEnabled false

proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’

}

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

学习福利

【Android 详细知识点思维脑图(技能树)】

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。

这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

详细整理在GitHub点击可见;

Android架构视频+BAT面试专题PDF+学习笔记

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

要的。

这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

[外链图片转存中…(img-f9n5KtkR-1711049097717)]

详细整理在GitHub点击可见;

Android架构视频+BAT面试专题PDF+学习笔记

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

  • 19
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值