Arouter源码阅读
2019-01-11 本文已影响7人
河里的枇杷树
自己的阅读笔记
一.从ARouter.init(context);
方法开始看,
-
LogisticsCenter.init()
方法,起作用是将arouter-compiler
生成的类解析,存储到sp中并且加载到内存中备用-
遍历所有dex 拿到 com.alibaba.android.arouter.routes 包下的所有类,存放到 Set 集合routerMap中,并将routerMap集合存放到Sp中
-
遍历routerMap集合 将集合内容分为
Root
Interceptors
Providers
三类分别将这三类中的内容存储到Warehouse
中的集合中备用
-
-
_ARouter.afterInit()
方法将拦截器服务启动。以后调用navigation()
方法都会出发拦截器(绿色通道除外)
二.ARouter.getInstance().build(url).navigation();
从这个链式调用开始看
-
看看
build(url)
干了什么?
这个方法干的事儿比较简单,只是通过传入的url确定了group,并返回一个Postcard
-
Postcard的navigation();
方法其实又调用到了_ARouter的navigation
方法-
_ARouter的navigation
方法中首先通过LogisticsCenter.completion(postcard);
方法将url
对应的RouteMeta
(路由数据)设置到Postcard
中 - 判断该次调用是否是绿色通道(
绿色通道的话会跳过所有拦截器
) - 对
Postcard
不同的type做不同的操作,type都包含ACTIVITY,PROVIDER,BOARDCASTCONTENT_PROVIDER,FRAGMENT,METHOD,SERVICE
-
3.看看当type是ACTIVITY
的时候回是怎么调到对应的Activity的
// Build intent
final Intent intent = new Intent(currentContext, postcard.getDestination());
intent.putExtras(postcard.getExtras());
// Set flags.
int flags = postcard.getFlags();
if (-1 != flags) {
intent.setFlags(flags);
} else if (!(currentContext instanceof Activity)) { // Non activity, need less one flag.
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
// Navigation in main looper.
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
if (requestCode > 0) { // Need start for result
ActivityCompat.startActivityForResult((Activity) currentContext, intent, requestCode, postcard.getOptionsBundle());
} else {
ActivityCompat.startActivity(currentContext, intent, postcard.getOptionsBundle());
}
if ((0 != postcard.getEnterAnim() || 0 != postcard.getExitAnim()) && currentContext instanceof Activity) { // Old version.
((Activity) currentContext).overridePendingTransition(postcard.getEnterAnim(), postcard.getExitAnim());
}
if (null != callback) { // Navigation over.
callback.onArrival(postcard);
}
}
});
可以看出来Arouter底层也是通过显示调用Activity的
4.看看当type是PROVIDER
的时候回是怎么实例化Provider的
// Its provider, so it must be implememt IProvider
Class<? extends IProvider> providerMeta = (Class<? extends IProvider>) routeMeta.getDestination();
IProvider instance = Warehouse.providers.get(providerMeta);
if (null == instance) { // There's no instance of this provider
IProvider provider;
try {
provider = providerMeta.getConstructor().newInstance();
provider.init(mContext);
Warehouse.providers.put(providerMeta, provider);
instance = provider;
} catch (Exception e) {
throw new HandlerException("Init provider failed! " + e.getMessage());
}
}
postcard.setProvider(instance);
postcard.greenChannel(); // Provider should skip all of interceptors
可以看出来当是Provider的时候直接用反射创建实例的