上一篇(https://www.jianshu.com/p/4ce5ec52d803)讲了注解处理器的使用,这次我们讲下ARouter
ARouter简介
ARouter由阿里巴巴开源,是一个用于组件化通信的框架(https://github.com/alibaba/ARouter)
ARouter页面跳转实现
ARouter是在组件化开发项目中发挥作用的,那么首先要了解下组件化的结构,其次为什么组件化需要使用框架进行通信
组件化
组件化开发有很多的优点,适用于大型项目,分工明确,调理清楚,可以实现模块单独打包,大大提升开发效率。通常一个组件化开发的项目结构大体是这样的。
截屏2021-01-24 下午3.32.43.png
它按照功能进行模块划分,每个模块都被app依赖,并且相互之间不存在依赖关系,所有的模块单独依赖底层基础模块library。这样一来,各功能之间就有明确的界限,高度解耦。
但是这样一来,因为没有相互依赖,模块间的通信就成了问题,如果我news模块中的一个页面想要做一个简单的页面跳转,跳转到home模块中的某个页面,怎么做呢,当然之前的文章中也有提到一些方法 https://www.jianshu.com/p/ed2c9f677e0e ,但是都不够好,缺点也不少。所以ARouter这样的框架才应运而生。
ARouter如何实现无依赖的页面跳转?
其实ARouter的实现方式和之前文章提到的全局map有点像,但是区别是什么呢,就是保存的过程不再是我们一个一个的添加了,而是编译器在编译过程中替我们做这些东西。这就涉及到了ARouter中的两个map。
GroupMap和PathMap
ARouter将项目工程的每个module划分为一个group也就是一个组,每个group有一个单独的名字,比如mine模块的group名就叫mine,而每个group下可以有多个类(目前类我们只表示Activity),每个需要被ARouter处理的类都要被ARouter注解,从而每个类都会有一个path来表示它的路径,所以它可以被ARouter找到,比如news模块下有一个MainActivity,那么它的group就是news,path就是/news/MainActivity
截屏2021-01-24 下午3.45.37.png那么如此一来,ARouter在编译期间通过找到这个模块中所有被注解的类,针对这个模块生成一个统一的辅助类,解析到每个被注解类的group和path,以注解的path为key,以类的相关信息为value,将这个类的信息保存到PathMap中。而使用map来存数据的目的也就是通过key来找到value,后边我们会提到这一点。
生成这个辅助类之后我们就有了一个pathMap,并且可以从pathMap中取出保存的类的信息,那么问题是,我们怎么找到这个辅助类呢,不找到这个类肯定是无法从这个类中取出pathMap的,所以groupMap就出现了。
groupMap就是以group名为key,以生成辅助类(pathMap所在类)的class文件全类名为value存储的。同样,它也是一个辅助类,看到这里我们知道了一点东西,每个module会存在两个被ARouter生成出来的辅助类,这两个类我们后边贴出来。
那么我们只要知道这个group名,就可以得到这个groupMap的辅助类,有了这个groupMap辅助类就可以获取到以group为key,以pathMap辅助类class为value的那个map了,反射就可以拿到pathMap所依附的对象,最后,有了这个对象,再次通过path这个key从里边就可以取出每个被ARouter注解的Activity了,有了Activity要实现跳转就太轻而易举了。
下边贴出两个辅助类的大概样子
groupMap
public class ARouter$$Group$$mine implements ARouterGroup {
@Override
public Map<String, Class<? extends ARouterPath>> getGroupMap() {
Map<String,Class<? extends ARouterPath>> groupMap = new HashMap<>();
groupMap.put("mine",ARouter$$Path$$mine.class);
return groupMap;
}
}
pathMap
public class ARouter$$Path$$mine implements ARouterPath {
@Override
public Map<String, RouterBean> getPathMap() {
Map<String,RouterBean> pathMap = new HashMap();
pathMap.put("/mine/MainActivity", RouterBean.create(RouterBean.TypeEnum.ACTIVITY, MainActivity.class, "/mine/MainActivity", "mine"));
return pathMap;
}
}
那么跳转的流程也来了
ARouter$$Group$$mine mine = new ARouter$$Group$$mine();
Map<String, Class<? extends ARouterPath>> groupMap = mine.getGroupMap();
Class<? extends ARouterPath> mineClass = groupMap.get("mine");
try {
ARouter$$Path$$mine aRouterPath = (ARouter$$Path$$mine) mineClass.newInstance();
Map<String, RouterBean> map = aRouterPath.getPathMap();
RouterBean routerBean = map.get("/mine/MainActivity");
Class<?> myClass = routerBean.getMyClass();
Intent intent = new Intent(this, myClass);
startActivity(intent);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
网友评论