前言
路由框架是干什么的:
首先看百度百科,路由_百度百科,“路由(routing)是指分组从源到目的地时,决定端到端路径的网络范围的进程。” 在Android程序里,相当于有一个可以帮用户转发两个客户的通信信息。比如页面路由转发,即Activity跳转,但这里的框架不限于此。
我需要么?
一般android开发中,进行页面跳转时,一般写法如下:
Intent intent = new Intent(mContext, XXActivity.class);
intent.putExtra(“key”,“value”);
startActivity(intent);
这样的写法通常导致依赖性增加,各种跳转添加的intent-filter不好维护,不利多人开发。项目做到一定程度,代码量和功能集都非常大,导致耦合严重,不利于应对功能变化。所以我们要组件化开发,分成多个module由不同的人开发,不同module间的通信和页面跳转就需要路由框架支持。
ARouter框架
ARouter:一个用于帮助 Android App 进行组件化改造的框架 —— 支持模块间的路由、通信、解耦。
准备知识:
要想理解本篇所涉及的知识,需要事先做一定的功课,如果都了解可以忽略。
- 注解知识,路由框架通过注解进行依赖注入。有需要可以参考:Android注解-看这篇文章就够了
- APT即注解处理器或者反射知识。由于本篇的注解类型相比与简单框架难度有所提高,有需要的可以参考:手写简化EventBus,理解框架核心原理,此篇为反射实现。 和手写简化EventBus之注解处理器方式,理解框架核心原理。 由于eventbus框架较简单,对此框架熟悉的可以先看此两篇文章加深过程印象。 对AutoService和javapoet有一定了解。
- javapoet, 模板文件生成代码的框架。可以自动按我们的设定去生成代码。
ARouter框架使用
想要学习一个框架,首先需要了解框架的基本使用,然后才能对框架中代码的作用有一定的了解,当然所有的源码都是为了使用设定的。由于框架目前的功能较多,这里只提纲挈领的介绍,最终我们自己动手撸框架也是实现其核心原理,否则,要实现一样功能集的框架那时间就太久了。如果想看详细说明,可以参见ARouter框架的git地址:https://github.com/alibaba/ARouter/blob/master/README_CN.md
添加依赖和配置
android {
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
//这里是在gradle配置中将module的名字作为参数传入,可以在注解处理器中的init方法中收到,用来生成不同的类文件
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
}
dependencies {
// 替换成最新版本, 需要注意的是api
// 要与compiler匹配使用,均使用最新版可以保证兼容
compile 'com.alibaba:arouter-api:x.x.x'
//每个使用了注解的module都需要添加,用来开始注解处理
annotationProcessor 'com.alibaba:arouter-compiler:x.x.x'
...
}
添加注解
// 在支持路由的页面上添加注解(必选)
// 这里的路径需要注意的是至少需要有两级,/xx/xx, 注解处理器生成模板代码时会根据第一级名字生成类名。
@Route(path = "/test/activity")
public class YourActivity extend Activity {
...
}
初始化SDK
ARouter.init(mApplication); // 尽可能早,推荐在Application中初始化
发起路由操作
// 1. 应用内简单的跳转(通过URL跳转在'进阶用法'中)
ARouter.getInstance().build("/test/activity").navigation();
// 2. 跳转并携带参数
ARouter.getInstance().build("/test/1")
.withLong("key1", 666L)
.withString("key3", "888")
.withObject("key4", new Test("Jack", "Rose"))
.navigation();
通过依赖注入解耦:服务管理(一) 暴露服务
由于我们不只会使用页面跳转,还会调用其他module提供的接口方法,也可以通过路由框架进行解耦,依赖注入。
// 声明接口,其他组件通过接口来调用服务,这里对外提供了一个方法接口,而此接口需要继承IProvider,用于路由框架知道此接口需要处理,即依赖注入。
public interface HelloService extends IProvider {
String sayHello(String name);
}
// 实现接口
@Route(path = "/yourservicegroupname/hello", name = "测试服务")
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String name) {
return "hello, " + name;
}
....
}
通过依赖注入解耦:服务管理(二) 发现服务
public class Test {
@Autowired
HelloService helloService;
@Autowired(name = "/yourservicegroupname/hello")
HelloService helloService2;
HelloService helloService3;
HelloService helloService4;
public Test() {
ARouter.getInstance().inject(this);
}
public void testService() {
// 1. (推荐)使用依赖注入的方式发现服务,通过注解标注字段,即可使用,无需主动获取
// Autowired注解中标注name之后,将会使用byName的方式注入对应的字段,不设置name属性,会默认使用byType的方式发现服务(当同一接口有多个实现的时候,必须使用byName的方式发现服务)
helloService.sayHello("Vergil");
helloService2.sayHello("Vergil");
// 2. 使用依赖查找的方式发现服务,主动去发现服务并使用,下面两种方式分别是byName和byType