Arouter框架适合项目比较大,模块多的时候,可以实现解耦,不需要知道跳转的是哪个activity,只需要知道配置参数就行
1.ARouter通过解析URL实现路由跳转
2.支持多模块使用,容许分别打包
3.Activity之间的跳转,普通的模式是
ARouter.getInstance().build("/test/MainActivity").withString("text","hello world") .navigation();
build里面是要跳转的目标,withString传递的是String类型的参数,navigation是跳转,一句代码完成跳转
4.在Application中进行初始化Arouter.init
public static void init(Application application) {
if(!hasInit) {
logger = _ARouter.logger;
_ARouter.logger.info("ARouter::","ARouter init start.");
hasInit = _ARouter.init(application);
if(hasInit) {
_ARouter.afterInit();
}
_ARouter.logger.info("ARouter::","ARouter init over.");
}
}
在 _ARouter.init(application)中调用了LogisticsCenter.init方法
在LogisticsCenter.init的方法中
public static synchronized void init(Context context, ThreadPoolExecutor tpe)throws HandlerException {
mContext = context;
executor = tpe;
try {
long e = System.currentTimeMillis();
Object routerMap;
if(!ARouter.debuggable() && !PackageUtils.isNewVersion(context)) {
ARouter.logger.info("ARouter::","Load router map from cache.");
routerMap =new HashSet(context.getSharedPreferences("SP_AROUTER_CACHE",0).getStringSet("ROUTER_MAP",new HashSet()));
}else {
ARouter.logger.info("ARouter::","Run with debug mode or new install, rebuild router map.");
routerMap = ClassUtils.getFileNameByPackageName(mContext,"com.alibaba.android.arouter.routes");
if(!((Set)routerMap).isEmpty()) {
context.getSharedPreferences("SP_AROUTER_CACHE",0).edit().putStringSet("ROUTER_MAP", (Set)routerMap).apply();
}
}
ARouter.logger.info("ARouter::","Find router map finished, map size = " + ((Set)routerMap).size() +", cost " + (System.currentTimeMillis() - e) +" ms.");
e = System.currentTimeMillis();
Iterator var5 = ((Set)routerMap).iterator();
while(var5.hasNext()) {
String className = (String)var5.next();
if(className.startsWith("com.alibaba.android.arouter.routes.ARouter$$Root")) {
((IRouteRoot)((IRouteRoot)Class.forName(className).getConstructor(new Class[0]).newInstance(new Object[0]))).loadInto(Warehouse.groupsIndex);
}else if(className.startsWith("com.alibaba.android.arouter.routes.ARouter$$Interceptors")) {
((IInterceptorGroup)((IInterceptorGroup)Class.forName(className).getConstructor(new Class[0]).newInstance(new Object[0]))).loadInto(Warehouse.interceptorsIndex);
}else if(className.startsWith("com.alibaba.android.arouter.routes.ARouter$$Providers")) {
((IProviderGroup)((IProviderGroup)Class.forName(className).getConstructor(new Class[0]).newInstance(new Object[0]))).loadInto(Warehouse.providersIndex);
}
}
ARouter.logger.info("ARouter::","Load root element finished, cost " + (System.currentTimeMillis() - e) +" ms.");
if(Warehouse.groupsIndex.size() ==0) {
ARouter.logger.error("ARouter::","No mapping files were found, check your configuration please!");
}
if(ARouter.debuggable()) {
ARouter.logger.debug("ARouter::", String.format(Locale.getDefault(),"LogisticsCenter has already been loaded, GroupIndex[%d], InterceptorIndex[%d], ProviderIndex[%d]",new Object[]{Integer.valueOf(Warehouse.groupsIndex.size()), Integer.valueOf(Warehouse.interceptorsIndex.size()), Integer.valueOf(Warehouse.providersIndex.size())}));
}
}catch (Exception var7) {
throw new HandlerException("ARouter::ARouter init logistics center exception! [" + var7.getMessage() +"]");
}
}
通过 ClassUtils.getFileNameByPackageName这个类获得所有的这个包名的类,将获得包名的类保存的sp中
5.除了app编译产生的类之外,arouter—api也会产生三个类
找到所有的类型之后,三个分支创判断类名的开头
com.alibaba.android.arouter.routes.ARouter$$Root
com.alibaba.android.arouter.routes.ARouter$$Interceptors
com.alibaba.android.arouter.routes.ARouter$$Providers
已Root开头的类:
public class ARouter$$Root$$appimplements IRouteRoot {
@Override
public void loadInto(Map> routes) {
routes.put("ui", ARouter$$Group$$ui.class);
}
}
public classARouter$$Root$$arouterapi implementsIRouteRoot{ @Override
public void loadInto(Map>routes) { routes.put("arouter", ARouter$$Group$$arouter.class);
}
}
第一个在自己的模块中产生的类,后缀为app
第二个在arouter-api中产生的类,后缀为arouterapi
(Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.groupsIndex);
利用反射,调用loadInto方法,传递过去的参数是Warehouse.groupsIndex
传过去的是一个静态的HashMap , 也就是说将“组”的信息 , 以“组名” , “组类”以键值对的方式存入了 , Warehouse 的 groupsIndex 里面 , 从名字上看就是存储“组”的 .
在WareHouse中providersIndex,这里是以 名称和RouteMeta为键值对存储 , RouteMeta保存着一些路由所需要的一些基本信息 ,
在ARouter.init中,调用调用了_ARouter.afterInit();进行了跳转
根据路径来进行跳转
public static synchronized void completion(Postcard postcard) {
if(null == postcard) {
throw new NoRouteFoundException("ARouter::No postcard!");
}else {
RouteMeta routeMeta = (RouteMeta)Warehouse.routes.get(postcard.getPath());
if(null == routeMeta) {
Class rawUri = (Class)Warehouse.groupsIndex.get(postcard.getGroup());
if(null == rawUri) {
throw new NoRouteFoundException("ARouter::There is no route match the path [" + postcard.getPath() +"], in group [" + postcard.getGroup() +"]");
}
try {
if(ARouter.debuggable()) {
ARouter.logger.debug("ARouter::", String.format(Locale.getDefault(),"The group [%s] starts loading, trigger by [%s]",new Object[]{postcard.getGroup(), postcard.getPath()}));
}
IRouteGroup providerMeta = (IRouteGroup)rawUri.getConstructor(new Class[0]).newInstance(new Object[0]);
providerMeta.loadInto(Warehouse.routes);
Warehouse.groupsIndex.remove(postcard.getGroup());
if(ARouter.debuggable()) {
ARouter.logger.debug("ARouter::", String.format(Locale.getDefault(),"The group [%s] has already been loaded, trigger by [%s]",new Object[]{postcard.getGroup(), postcard.getPath()}));
}
}catch (Exception var8) {
throw new HandlerException("ARouter::Fatal exception when loading group meta. [" + var8.getMessage() +"]");
}
completion(postcard);
}else {
postcard.setDestination(routeMeta.getDestination());
postcard.setType(routeMeta.getType());
postcard.setPriority(routeMeta.getPriority());
postcard.setExtra(routeMeta.getExtra());
Uri rawUri1 = postcard.getUri();
if(null != rawUri1) {
Map providerMeta1 = TextUtils.splitQueryParameters(rawUri1);
Map instance = routeMeta.getParamsType();
if(MapUtils.isNotEmpty(instance)) {
Iterator provider = instance.entrySet().iterator();
while(provider.hasNext()) {
Entry e = (Entry)provider.next();
setValue(postcard, (Integer)e.getValue(), (String)e.getKey(), (String)providerMeta1.get(e.getKey()));
}
postcard.getExtras().putStringArray("wmHzgD4lOj5o4241", (String[])instance.keySet().toArray(new String[0]));
}
postcard.withString("NTeRQWvye18AkPd6G", rawUri1.toString());
}
switch(null.$SwitchMap$com$alibaba$android$arouter$facade$enums$RouteType[routeMeta.getType().ordinal()]) {
case 1:
Class providerMeta2 = routeMeta.getDestination();
IProvider instance1 = (IProvider)Warehouse.providers.get(providerMeta2);
if(null == instance1) {
try {
IProvider provider1 = (IProvider)providerMeta2.getConstructor(new Class[0]).newInstance(new Object[0]);
provider1.init(mContext);
Warehouse.providers.put(providerMeta2, provider1);
instance1 = provider1;
}catch (Exception var7) {
throw new HandlerException("Init provider failed! " + var7.getMessage());
}
}
postcard.setProvider(instance1);
postcard.greenChannel();
break;
case 2:
postcard.greenChannel();
}
}
}
}
1. build()返回一个PostCard对象 , 包含路径 , 组名
2,调用PostCard的navigation()方法 , navigation()方法中调用LogisticsCenter.completion()方法并把包含路径 , 组名的postCard传过去 .
3.在warehouse中进行搜索,首先会从routes中寻找着信息,如果没有,去groupIndex中寻找,找到了相应的信息,添加到routes缓存中,并存groupIndex中去掉
4.找到相应的类之后,再去postCard,再去设置类,类型优先级,传递过去的额外数据
5.接着根据postCard类型判断,如果是fragment或者是provider,就就去绿色通道,如果没有手动设置,会被arouter-api中的全局拦截器被拦截掉
在跳转中
private Object _navigation(Context context,final Postcard postcard,final int requestCode,final NavigationCallback callback) {
final Context currentContext =null == context?mContext:context;
switch(null.$SwitchMap$com$alibaba$android$arouter$facade$enums$RouteType[postcard.getType().ordinal()]) {
case 1:
final Intent intent =new Intent(currentContext, postcard.getDestination());
intent.putExtras(postcard.getExtras());
int flags = postcard.getFlags();
if(-1 != flags) {
intent.setFlags(flags);
}else if(!(currentContextinstanceof Activity)) {
intent.setFlags(268435456);
}
(new Handler(Looper.getMainLooper())).post(new Runnable() {
public void run() {
if(requestCode >0) {
ActivityCompat.startActivityForResult((Activity)currentContext, intent, requestCode, postcard.getOptionsBundle());
}else {
ActivityCompat.startActivity(currentContext, intent, postcard.getOptionsBundle());
}
if((0 != postcard.getEnterAnim() ||0 != postcard.getExitAnim()) && currentContextinstanceof Activity) {
((Activity)currentContext).overridePendingTransition(postcard.getEnterAnim(), postcard.getExitAnim());
}
if(null != callback) {
callback.onArrival(postcard);
}
}
});
return null;
case 2:
return postcard.getProvider();
case 3:
case 4:
case 5:
Class fragmentMeta = postcard.getDestination();
try {
Object ex = fragmentMeta.getConstructor(new Class[0]).newInstance(new Object[0]);
if(exinstanceof Fragment) {
((Fragment)ex).setArguments(postcard.getExtras());
}else if(exinstanceof android.support.v4.app.Fragment) {
((android.support.v4.app.Fragment)ex).setArguments(postcard.getExtras());
}
return ex;
}catch (Exception var10) {
logger.error("ARouter::","Fetch fragment instance error, " + TextUtils.formatStackTrace(var10.getStackTrace()));
}
case 6:
case 7:
default:
return null;
}
}
根据type来执行操作