前言
上一篇ARouter类简单介绍已经介绍了Arouter涉及的主要类和作用。以及ARouter-简单路由跳转中也讲述了怎么实现跳转。现在剖析源码分析下Activity跳转过程?(参考:https://www.jianshu.com/p/fa4c4749dd95 )
Activity跳转流程
1.跳转代码:
ARouter.getInstance()
.build("/app/ListPage")
.withString("name", "来自主页")
.navigation(ArouterMainActivity.this, 100, new NavigationCallback(){
@Override
public void onFound(Postcard postcard) {
}
@Override
public void onLost(Postcard postcard) {
}
});
步骤一:构建PostCard(包括路径 分组等信息)
ARouter.getInstance().build("/app/ListPage")
build最终会调用到_Arouter的以下方法navigation方法:
protected T navigation(Class<? extends T> service) {
try {
Postcard postcard = LogisticsCenter.buildProvider(service.getSimpleName());
LogisticsCenter.completion(postcard);
return (T) postcard.getProvider();
} catch (NoRouteFoundException ex) {
logger.warning(Consts.TAG, ex.getMessage());
return null;
}
}
其中, LogisticsCenter.buildProvider功能是获取provider,针对activity跳转是啥也没有做的。
获取provider如下:
public static Postcard buildProvider(String serviceName) {
RouteMeta meta = Warehouse.providersIndex.get(serviceName);
if (null == meta) {
return null;
} else {
return new Postcard(meta.getPath(), meta.getGroup());
}
}
LogisticsCenter.completion(postcard);功能是完善postcard信息。
先要加载路由表 :
从仓库查找是否有该组路由,
RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath());
如果为空,从groupsIndex路由中得到分组路由
Class<? extends IRouteGroup> groupMeta = Warehouse.groupsIndex.get(postcard.getGroup()); // Load route meta.
加载路由到内存routes:
IRouteGroup iGroupInstance = groupMeta.getConstructor().newInstance();
iGroupInstance.loadInto(Warehouse.routes);
Warehouse.groupsIndex.remove(postcard.getGroup());
再根据路由表,完善postcard:
postcard.setDestination(routeMeta.getDestination()); //设置目标类
postcard.setType(routeMeta.getType()); //类型: ACTIVITY SERVICE等
postcard.setPriority(routeMeta.getPriority()); //优先级
postcard.setExtra(routeMeta.getExtra()); //额外参数
这样,postcard中就包括了:
private Class<?> destination; // Destination
private String path; // Path of route
private String group; // Group of route
private int priority = -1; // The smaller the number, the higher the priority
private int extra; // Extra data
private RouteType type; // Type of route
步骤二、添加数据
withString(“name”, “来自主页”):添加数据到Postcrard的Bundle中(最后跳转时候会从postcard中获取bundle数据,传递给下一个activity)
public Postcard withString(@Nullable String key, @Nullable String value) {
mBundle.putString(key, value);
return this;
}
步骤三、跳转
navigation:导航跳转
1.首先会将数据再次进行完善:
LogisticsCenter.completion(postcard);
然后回调onFound通知已经找到postcard
if (null != callback) {
callback.onFound(postcard);
}
2.判断postcard是否为绿色通道,不用拦截,是的话,就跳转:
代码是不是很熟悉:首先创建intent。
final Intent intent = new Intent(currentContext, postcard.getDestination());
再设置flags;
再通过主线程startActivityForResult。这样就完成了activity的跳转。
switch (postcard.getType()) {
case 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());
}
}
});
break;
同样的,支持provider的实例获取。也是一样的流程,只是细节有差异。