标签(空格分隔): 框架原理理解
仅限于个人理解,不建议阅读
定义两个类 :一个类为组表,一个类为路由表;
组表<key,value>---><组名,组名类>
路由表<key,value>---><路径名,对应的Class>
路由表为一个类,里面的map装载的为当前组下所有的路由
组表为一个类,里面的map装载的为当前模块下所有的组名类(也就是一个路由表类[见上])
- 注解生成器搜索Route注解,获取到跟注解能扯上关系的信息[path,group,当前标注的Class<Activity>],也就是RouteMeta
- 然后对所有的RouteMeta进行分组;先验证注解的value是否合法,也就是路径path和group;然后针对每一个组都建立一个List<RouteMeta>,然后将一个Map<String,List<RouteMeta>>将所有的路由表也装载起来;(可以理解为一棵树,这个map是大树,枝丫就是所有的组名,组名下面的枝丫就是该组下对应的所有路由)
- 以上路由信息采集完毕,开始生成代码;生成路由表,生成组表;
- 路由表生成:定义了一个接口,在接口中,将全局的Map作为参数传递进来;实现类中将该组下的所有路由装载进去Map< path , Class > (有点像所有小区都租出去了,然后总负责人到每个小区的收费总入口把所有人的房租收起来);拼装路由表类代码(javapoet);同时收集所有的组名到map< groupName, groupClassName>中;
- 组表生成:定义一个接口,在接口中,将全局Map作为参数传递进来;实现类中将该模块下的所有组名装载进去Map< groupName, groupNameClass> (这样就像将北京城的东城区,西城区...的总负责人聚集到了一块,北京模块直接齐全了);拼接路由表类代码;
- 以上两个主要类就生成完了,主要就是搜集所有模块的所有组下的所有路由;
- 然后在Application启动的时候,传入当前上下文,然后加载这两种类型的所有类;定义一个全局的路由表和模块表进行收集;咋收集的:初始化时,遍历过滤拿到所有的模块类,搜集全局的组表<组名,组名类>;然后在使用时,去全局路由表<path,pathClass>中去查询,没找到就先全局组表中找到组名类,然后创建组名类的实例化,调用他的接口方法,传入全局路由map,将所有的路由加入到全局路由map中,该组加载完就移除;这是一种懒加载方式,用到哪个组就加载哪个组,当然如果一个组里面太多路由,全部执行一遍添加就有损效率的,所以一个组的大小需要把控一下;继续,找到对应的pathClass后就通过Intent执行跳转;
使用:
@Route(path = "/main/MainActivity", group = "app")
public class MainActivity extends AppCompatActivity {}
@Route(path = "/main/SecondActivity", group = "app2")
public class SecondActivity extends AppCompatActivity {}
ARouter.init(this);//Application
对应的定义的代码:
public interface IRouteGroup {
void loadInto(Map<String, RouteMeta> atlas);
}
public interface IRouteRoot {
/**
* @param routes input
*/
void loadInto(Map<String, Class<? extends IRouteGroup>> routes);
}
以及生成的代码:
public class ARouter$$Root$$app implements IRouteRoot {
@Override
public void loadInto(Map<String, Class<? extends IRouteGroup>> routes) {
routes.put("app",DNRouter$$Group$$app.class);
routes.put("app2",DNRouter$$Group$$app2.class);
}
}
public class ARouter$$Group$$app implements IRouteGroup {
@Override
public void loadInto(Map<String, RouteMeta> atlas) {
atlas.put("/main/MainActivity",RouteMeta.build(RouteMeta.Type.ACTIVITY,MainActivity.class,"/main/mainactivity","app"));
}
}
public class ARouter$$Group$$app2 implements IRouteGroup {
@Override
public void loadInto(Map<String, RouteMeta> atlas) {
atlas.put("/main/SecondActivity",RouteMeta.build(RouteMeta.Type.ACTIVITY,SecondActivity.class,"/main/secondactivity","app2"));
}
}