ARouter是我弄组件化的时候用到的
因为组件化就保证了有不同的module,不同的module它都依赖于一个base_module。因为不同的module,所以我们没办法使用Intent进行跳转,于是使用了ARouter进行各个module之间的通信
我们可以在module于base_module之间添加一个路由模块,让这个路由模块来管理它们之间的路由
也就可以这么理解,以前的人们要把信件传递给别人,首先要把信件给邮局,然后邮局再把信给你要寄出去的那个人
这里邮局就是ARouter,它可以帮助相互没有依赖的组件进行跳转和通讯
1.ARouter的原理
ARouter在Activity中的跳转很简单,就是初始化ARouter,添加注解,发起路由
1:初始化ARouter// 在module app中
//1.初始化SDK
ARouter.init(mApplication); // 尽可能早,推荐在Application中初始化
2:添加注解// moduleA
// 2.在支持路由的页面上添加注解(必选)
// 路径注意至少需有两级,/xx/xx
@Route(path = "/test/activity")
public class YourActivity extend Activity {
...
}
3.发起路由跳转// moduleB(没有依赖 moduleA)
// 3.发起路由跳转
ARouter.getInstance().build("/test/activity").navigation();
其中@Route注解被称之为路由地址
ARouter的整个原理就是:ARouter通过Apt技术,生成保存路径(路由path)和路由地址(Route)的一个映射关系的类,理由这些保存了映射关系的类,ARouter就可以根据用户的请求跳转到对应的目标地址
Apt将我们配置的注解与对应的Activity保存到一个Map中
就比如下面这样class RouterMap {
public Map getAllRoutes {
Map map = new HashMap<String,Class<?>>;
map.put("/test/activity",TestActivity.class);
map.put("/main/setting",SettingActivity.class);
map.put("/login/register",LoginRegisterActivity.class);
....
return map;
}
}
然后将这个map加载到内存,需要的时候直接通过get(path)就可以了
2.APT的原理
刚才我们说了ARouter就是通过APT将我们写的注解和对应的Activity放到一个Map中,让后ARouter就是通过这个map进行的跳转
APT的作用就是在编译阶段扫描并处理代码中的注解,然后根据注解输出Java文件
ARouter为了方便实现注解处理器还额外用了两个库。
- 一个是JavaPoet,他提供了调用对象方法的方式生成需要的代码,而不再需要人为的用StringBuilder去拼接代码,再使用IO写入文件。
- 一个是Auto-Service,他提供了简便的方式去注册APT,避免了原本繁琐的注册步骤。
2.1@Route
Route的定义是注解:@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface Route{
/**
* Path of route
*/
String path();
……
}
- @Target({ElementType.TYPE})——表示这个annotation是修饰类的
- @Retention(RetentionPolicy.CLASS)——表示需要保留到编译时
Route中有一个主要的参数path,他表示了Activity的路由地址。@Route(path = RouteHub.QRCode.QRCODE_SCAN_PATH)
第一个@Target说实话不知道它是干嘛的,但是第二个@Retention这个还是得好好注意一下,表示下面的那个path要保留到编译的时候
3.ARouter的一个整体流程
我们在代码里加入的@Route注解,会在编译时期通过apt生成一些存储path和activityClass映射关系的类文件,然后app进程启动的时候会拿到这些类文件,把保存这些映射关系的数据读到内存里(保存在map里),然后在进行路由跳转的时候,通过build()方法传入要到达页面的路由地址,ARouter会通过它自己存储的路由表找到路由地址对应的Activity.class(activity.class = map.get(path)),然后new Intent(),当调用ARouter的withString()方法它的内部会调用intent.putExtra(String name, String value),调用navigation()方法,它的内部会调用startActivity(intent)进行跳转,这样便可以实现两个相互没有依赖的module顺利的启动对方的Activity了。
我稍微简化一下就是,@Route这个我们在上面讲过,就是它会在将你注解写的那个路径一直保存在编译的时候,在编译的时候通过apt生成存储path和activityClass的一个map,当app进程启动的时候会通过这个map把这个map读到内存里面,在路由跳转也就是的时候,通过build传入你的那个注解比如/test/activity。然后在内存的map中找到这个注解对应的activityclass,然后new Intent(),
当你想通过ARouter再传些值的时候再调用ARouter.withString()方法,它其实就是在内部调用了Intent.putExtra()
调用navigation()会在内部调用startActivity
就是
当你ARouter.build(xxxx)的时候就是new Intent()
当你ARouter.withString()的时候就是Intent.putExtra()
当你ARouter.navigation()的时候就是Intent.startActivity()
3.1添加注解
在使用ARouter的时候,你首先先得给你需要跳转的Activity或者Fragment等类的前面添加注解,注明他的路径。添加注解的时候,ARouter就会根据你添加的注解通过APT自动生成对应的三个类:Group、Providers、Root。
- Group 类:生成的 Group 类是根据路径中的分组信息生成的,用于路由的分组管理。每个 Group 类都包含一个静态的
loadInto(Map<String, Class<? extends IRoute>> routes)
方法,在该方法中将目标类与路径进行关联。 - Providers 类:生成的 Providers 类用于存储路径对应的具体类的信息,
- Root 类:生成的 Root 类是整个路由框架的入口类,用于初始化路由框架。Root 类中包含一个静态的
loadInto(Map<String, Class<? extends IRoute>> routes)
方法,在该方法中会加载所有生成的 Group 类并注册路由信息。
简单记忆就是
Root类是路由的初始化
Group是路径的分组
Providers是存储路径和类(就是Activity.class)的映射关系
3.2初始化
当你调用ARouter的init方法时,他就会有一个类叫Warehouse,这个类里面只有3组也就是6个静态类型的Map,对应着我们刚刚说的APT自动生成的那三个类,分别是route的map、provider的map以及拦截器Interceptor的map。
然后init就会拿到所有配置了route的类,按照不同的属性分别加到三个map里面去。
调用init方法后会调用_ARouter的afterinit方法,这个方法最后会返回一个根据path和group来new好的一个Postcard对象,这个Postcard就是用来存放跳转所需信息,也就是说我们在通过ARouter传值的时候,设定的值都先放在这个Postcard里面。
3.2.1注意:
Interceptor的好理解,它就是存拦截器的
那么另外两个呢?
Route是用来存跳转的界面的那个注解和跳转界面的activity.class
但是Provider是存的是注解和你要跳转的Service的
3.3跳转
然后当我们需要跳转的时候,实际上调用的是ARouter的navigation方法,在这个方法中就会new一个intent,然后把postcard中存储的activity传进去,接着如果你配置了Extra,就会调用intent的putExtra方法把postcard中的Extra给传进去,同样的,如果你设置了Flag也是把postcard的Flag传给intent,action也是从postcard传给intent。等extra、flag、action都配置好了之后,就通过runInMainThread回到主线程然后调用startActivity跳转过去。
其中runInMainThread是通过得到主线程的Looper,再判断当前线程是不是主线程,如果不是就通过handler发消息,如果是就直接run。startActivity也是_ARouter自己的方法,基本上都是通过ActivityCompat调用startActivityForResult或者startActivity进行跳转。
就是调用navigation就会把postCard中保存的参数全部传给Intent,然后都配置好后通过runInMainThread回到主线程然后调用startActivity跳转过去
Comments | NOTHING