前言
春节后的第一篇分享,工作状态也慢慢找回来。本文将给大家带来的分享是ARouter的的原理介绍,通过了解它的原理,我们可以知道它是如何支持组件化和不互相依赖的模块间进行调用或者页面的跳转。
正文
ARouter介绍
ARouter是阿里开源的一个用于进行组件化的路由框架,它可以帮助互不依赖的组件间进行页面跳转和服务调用。
ARouter使用
添加依赖:
android {
//...
defaultConfig {
kapt {
arguments {
arg("AROUTER_MODULE_NAME", project.getName())
}
}
}
//...
}
dependencies {
api 'com.alibaba:arouter-api:1.5.0'
kapt 'com.alibaba:arouter-compiler:1.2.2'
}
定义跳转Activity的path:
@Route(path = "/test/router_activity")
class RouterActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_router)
}
}
初始化Router框架:
class RouterDemoApp : Application() {
override fun onCreate() {
super.onCreate()
//初始化、注入
ARouter.init(this)
}
}
调用跳转:
ARouter.getInstance().build("/test/router_activity").navigation()
生成的代码(生成的路由表)
当我们给Activity或者服务等加上Route注解后,build一下,ARouter框架便会按照模版帮我们生成java文件,并且是在运行的时候可以访问的。其中使用的技术是apt技术。下面我们一起看看上边的示例生成的代码:
public class ARouter$$Root$$app implements IRouteRoot {
@Override
public void loadInto(Map<String, Class<? extends IRouteGroup>> routes) {
routes.put("test", ARouter$$Group$$test.class);
}
}
public class ARouter$$Group$$test implements IRouteGroup {
@Override
public void loadInto(Map<String, RouteMeta> atlas) {
atlas.put("/test/router_activity", RouteMeta.build(RouteType.ACTIVITY, RouterActivity.class, "/test/router_activity", "test", null, -1, -2147483648));
}
}
根据上边生成的代码可以看出,生成的代码就是一张路由表,先将群组跟群组的class对应起来,每个群组里边是该群组下的路由表。
初始化init()(加载路由表的群组)
接下来我们看看初始化时,路由框架里边做了哪些事情:
//#ARouter
public static void init(Application application) {
if (!hasInit) {
//...省略部分代码
hasInit = _ARouter.init(application);
//...省略部分代码
}
}
//#_ARouter
protected static synchronized boolean init(Application application) {
mContext = application;
LogisticsCenter.init(mContext, executor);
logger.info(Consts.TAG, "ARouter init success!");
hasInit = true;
mHandler = new Handler(Looper.getMainLooper());
return true;
}
初始化的核心代码看起来就在LogisticsCenter中:
public synchronized static void init(Context context, ThreadPoolExecutor tpe) throws HandlerException {
mContext = context;
executor = tpe;
try {
//...省略代码
if (registerByPlugin) {
//...省略代码
} else {
Set<String> routerMap;
// 如果是debug包或者更新版本