ARouter原理(一):什么是组件化,组件化解决的问题是什么?你会了解到Dex是什么,APT是什么?

目录

在这里插入图片描述


一、什么是组件化?组件化解决什么问题?

1.1 为什么要使用组件化吗?

我们先看看,一般我们创建出来的项目,只有一个App模块。那么只有一个开发模块会遇到什么问题?

`

  1. 问题一:在实际开发中,我们可能会负责多个项目,并且以前项目里面的内容可能会在其他项目里面使用。好,那么如果我们所有业务逻辑都写在app模块里面,那么复制迁移的时候,就非常麻烦。
  2. 问题二:项目小的时候还好说,随着需求越来越多,项目越来越多,那么就会遇到很多的问题,比如分包问题,逻辑混杂,接手吃力,代码高度耦合。
  3. 问题三:不利于多人联合开发,在版本管理中,很容器出现冲突和代码覆盖的问题。

1.2 什么是组件化

组件化是指将一个复杂的系统或应用拆分成多个相对独立、功能单一的组件(或模块)。

在Android工程中,这通常意味着将app按照其业务功能的不同,划分为不同的Module(模块)。这样就解决了问题一和问题二。

每个Module都可以看作是一个小型的应用,具有独立的开发、编译和测试的能力,就像一个app一样。这样就解决问题三。

这些模块的的特点

1、各个组件专注自身功能的实现,模块中代码高度聚合,只负责一项任务,也就是常说的单一责任原则;
2、各业务研发可以互不干扰、提升协作效率;
3、业务组件可进行拔插,灵活多变;
4、业务组件之间将不再直接引用和依赖,各个业务模块组件更加独立,降低耦合;
5、加快编译速度,提高开发效率;

下面我们看一个结构图

在这里插入图片描述

  1. App壳:负责管理各个业务组件和打包apk,没有具体的业务功能
    在这里插入图片描述在这里插入图片描述

2.业务组件层:根据不同的业务构成独立的业务组件;每个业务组件都能独立运行,并可以作为一个完整的App进行调试和测试。这种独立性使得业务组件的开发、维护和测试变得更加高效。在组件化架构中,业务组件通常会被集成到应用层(壳组件)中,以组合成一个完整的App。

3.功能组件层:它们不依赖于任何特定的业务逻辑,而是提供了一套通用的接口或API供其他组件调用。上图可以看到,调试组件可以整合功能组件(日志组件、登录组件)进行使用。

4.基础库:包含了各种开源库以及和业务无关的各种自研工具库。

思考一个问题:为什么不能横向依赖呢?因为这样会导致依赖循环,并且application不能依赖application。


1.3 Application插件和Library插件

Application

Application插件是Gradle构建系统的一个插件,主要用于创建可执行的应用程序。以确保应用能够正确编译、打包并运行在Android设备上。

主要作用:

  1. 项目配置:配置应用的基本信息,如应用名称、图标、版本号等。
  2. 依赖管理:管理应用所需的第三方库和模块,确保它们能够正确集成到应用中。
  3. 资源处理:处理应用的资源文件,如图片、布局文件等,以便在应用中正确使用。
  4. 编译与打包:将应用的源代码和资源编译成可执行的APK文件,供用户安装和使用。

如果我们把这个给注释掉,那么这些全部无法使用。

在这里插入图片描述

Library

Library插件通常用于构建和打包库文件(如JAR、AAR等),这些库文件可以被其他应用程序或库所依赖和使用。

主要作用:

  1. 建库文件:Library插件提供了构建库文件所需的功能,包括编译源代码、处理资源文件等
  2. 打包依赖项:能够将库文件及其依赖项打包成一个或多个易于分发的包,这些包可以被其他项目作为依赖项引入
  3. 管理依赖关系:Library插件通常还包含管理项目依赖关系的机制,确保项目能够正确地找到并使用所需的库文件
  4. 促进模块化:通过使用Library插件构建库文件,开发者可以将大型项目拆分成多个较小的、更易于管理的模块,从而提高项目的可维护性和可扩展性。

组件化,说白了就是在玩gradle


二、组件之间如何通讯?

组件之间禁止相互依赖,如何在不同的组件之间进行页面的跳转?

以前,我们可以通过Intent来进行Activity的跳转,但是现在Activity在不同的业务组件,那么又如何实现跳转呢?

在这里插入图片描述

显式跳转不行了,那么隐式呢?是可以的。

在这里插入图片描述
这样我们就不需要给这个Activity的引用,直接传递Action就可以。

但如果使用过路由,就会发现比这个简单了很多,那么路由是如何实现的?


2.1 路由框架的原理

在这里插入图片描述
在这里插入图片描述
我们可以看到,我们通过注解,将一个字符串和一个Activity进行了绑定。其实就类似于一个Map,页面跳转的时候,就通过这个字符串去找到这个Activity,这样就可以new Intent去跳转了。


2.2 那么对照到我们的代码当中,应该如何实现?DexFile

我们看一个简单的路由实现,最基基基础的实现。

  1. 创建一个Map
  2. 进行注册
    在这里插入图片描述

注册到路由表

在这里插入图片描述
但这里存在一个问题,如果你要把这个框架打包给别人用,如果类很多,那么要写很多这样的代码,不方便,并且会导致Application比较臃肿。
在这里插入图片描述
在这里插入图片描述
自己负责注册自己的路由,实现解耦,实现下沉到各个模块。但,这个FoodRouter应该在哪里调用?什么时候调用loadInto方法?
在这里插入图片描述
提供一个init方法。但我们知道,App层,是壳,没有方法拿到FoodRouter类,那么怎么办呢?使用反射。但不能使用全限定类名,因为你不知道别人的要注册的是那个类。

但,我们知道,所有的类,都会打包进入这个Apk里面,都会进入DEX文件。那么有没有方法在程序运行期间,拿到这个apk文件。可以的!那么如何拿?PMS(Package Manager Service)拿到Apk文件后,就可以拿到Dex文件,那么如何操作Dex文件?有没有方法可以把里面包含的类给遍历出来?那么用什么来操作Dex文件?DexFile来进行操作(具体代码可以上网搜索一下)。拿到所有的类进行遍历,如果实现了IRouteLoad接口,那么就是需要进行注册的,我们就可以使用反射实例化这个类,然后调用loadInto方法,添加路由进去。

在这里插入图片描述
这样我们就可以直接调用init方法进行初始化了。是不是写法和我们使用别人的第三方库,一毛一样。
在这里插入图片描述

但有个地方还是比较麻烦。因为开发者还需要写一个这样的类,包名,并且是每一个模块都要写。还是比较麻烦。

在这里插入图片描述
接下来我们就要使用APT技术,APT技术主要是用来生成类。


2.3 使用APT技术来自动生成类,来解决我们需要写重复代码的问题

上面也说到,如果我们有很多的模块,比如调试模块,串口测试模块,那么就都要写一个FoodRouter类,非常麻烦,然后我们发现这些类都有一个共同的特点,就是很相似。固定的包名,固定的实现接口,固定要实现的方法。除了数据不一样,类结构都一样。像这种,就是模板代码。像我们以前使用的findviewById方法一样,别的第三方框架也是解决了这种问题。

接下来我们要使用到一个技术:APT。

APT:注解处理器,是javac处理注解的一种工具,它用来在编译时扫描和处理注解。简单来说就是在编译期,通过注解采集信息,生成.java文件。减少重复的代码的编写。

下面我们来使用看看。
1.先看一个注解,我们看如何采集他的信息,然后生成一个Java类。
在这里插入图片描述
在这里插入图片描述
2.注解处理器
(1)要继承AbstractProcessor,使其成为一个注解处理器
在这里插入图片描述
(2)要进行注册:写上注解处理器的全类名

在这里插入图片描述
在这里插入图片描述
(3)指定要处理的注解,因为注解有太多了,所以要指定:
在这里插入图片描述

那么注解处理器是在什么时候执行?
在这里插入图片描述
在这里插入图片描述在准备编译之后,在开始编译之前。所以如果我们在这里生成的类,那么就可以打包进入apk里面。接下来我们就来试一下生成FoodRouter类,那么如何生成?

说白了就是生成一个Java文件,那么我们就可以使用流的方式去生成一个文件,然后将代码写入进去,不就可以了嘛。
在这里插入图片描述
但生成在哪里?我们不能写死目录。其实注解处理器,给我们提供了文件工具
在这里插入图片描述
编译一下,我们就可以看到生成了。
在这里插入图片描述
(4)下面我们再来看一个问题,这里的名字是固定的,但如果我模块变了呢,我这里的名字也要变呀。应该怎么办?

在这里插入图片描述
要得到模块的名字。我们可以在gradle里面配置注解处理器的参数。
在这里插入图片描述
在这里插入图片描述
还需要配置接收哪些参数。
在这里插入图片描述
到这里为止,我们只需要如下这样,就可以使用跳转了,是不是已经很方便了。
在这里插入图片描述

好了,这篇文章就写到这里~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前期后期

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值