protected Object navigation(final Context context, final Postcard postcard, finalint requestCode, final NavigationCallback callback){ try { //完善postCard 核心信息,主要是跳转路径 后面会详细分析 LogisticsCenter.completion(postcard); } catch (NoRouteFoundException ex) { // 未找到页面的降级处理策略 if (null != callback) { //自定义回调高于系统 callback.onLost(postcard); } else { // No callback for this invoke, then we use the global degrade service. //没有自定义回调才使用系统onLost DegradeService degradeService = ARouter.getInstance().navigation(DegradeService.class); if (null != degradeService) { degradeService.onLost(context, postcard); } }
returnnull; }
if (null != callback) { //onFound回调 callback.onFound(postcard); }
if (!postcard.isGreenChannel()) { // It must be run in async thread, maybe interceptor cost too mush time made ANR. //非绿色通道检查拦截器 interceptorService.doInterceptions(postcard, new InterceptorCallback() { @Override publicvoidonContinue(Postcard postcard){ //真正核心导航逻辑 _navigation(context, postcard, requestCode, callback); }
private Object _navigation(final Context context, final Postcard postcard, finalint requestCode, final NavigationCallback callback){ final Context currentContext = null == context ? mContext : context;
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); } elseif (!(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 publicvoidrun(){ if (requestCode > 0) { // Need start for result ActivityCompat.startActivityForResult((Activity) currentContext, intent, requestCode, postcard.getOptionsBundle()); } else { ActivityCompat.startActivity(currentContext, intent, postcard.getOptionsBundle()); }
if ((-1 != postcard.getEnterAnim() && -1 != postcard.getExitAnim()) && currentContext instanceof Activity) { // Old version. ((Activity) currentContext).overridePendingTransition(postcard.getEnterAnim(), postcard.getExitAnim()); }
publicsynchronizedstaticvoidcompletion(Postcard postcard){ …… //从仓库WareHouse中获取路由元数据,即一些路由基本的数据 RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath()); if (null == routeMeta) { // Maybe its does't exist, or didn't load. Class<? extends IRouteGroup> groupMeta = Warehouse.groupsIndex.get(postcard.getGroup()); // Load route meta. if (null == groupMeta) { thrownew NoRouteFoundException(TAG + "There is no route match the path [" + postcard.getPath() + "], in group [" + postcard.getGroup() + "]"); } else { // Load route and cache it into memory, then delete from metas. try { …… //将信息加载进Warehouse.routes中 IRouteGroup iGroupInstance = groupMeta.getConstructor().newInstance(); iGroupInstance.loadInto(Warehouse.routes); Warehouse.groupsIndex.remove(postcard.getGroup()); …… } …… //经过上面的处理后,此时可以获取到对应path下的routeMeta,调用本身 completion(postcard); // Reload } } else { //正常获取到routeMeta填充postCard信息 postcard.setDestination(routeMeta.getDestination()); postcard.setType(routeMeta.getType()); postcard.setPriority(routeMeta.getPriority()); postcard.setExtra(routeMeta.getExtra());
Uri rawUri = postcard.getUri(); if (null != rawUri) { // Try to set params into bundle. Map<String, String> resultMap = TextUtils.splitQueryParameters(rawUri); Map<String, Integer> paramsType = routeMeta.getParamsType();
if (MapUtils.isNotEmpty(paramsType)) { // Set value by its type, just for params which annotation by @Param for (Map.Entry<String, Integer> params : paramsType.entrySet()) { setValue(postcard, params.getValue(), params.getKey(), resultMap.get(params.getKey())); }
// Save params name which need auto inject. postcard.getExtras().putStringArray(ARouter.AUTO_INJECT, paramsType.keySet().toArray(new String[]{})); }
// Save raw uri postcard.withString(ARouter.RAW_URI, rawUri.toString()); }
switch (routeMeta.getType()) { //完成信息的同时顺便把"服务实例化",fragment置为无须过滤的绿色通道 case PROVIDER: // if the route is provider, should find its instance // Its provider, so it must implement 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) { thrownew HandlerException("Init provider failed! " + e.getMessage()); } } postcard.setProvider(instance); postcard.greenChannel(); // Provider should skip all of interceptors break; case FRAGMENT: postcard.greenChannel(); // Fragment needn't interceptors default: break; } } }