* LogisticsCenter contains all of the map.
*
* 1. Creates instance when it is first used.
* 2. Handler Multi-Module relationship map(*)
* 3. Complex logic to solve duplicate group definition
/** * DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY AROUTER. */ publicclassARouter$$Root$$appimplementsIRouteRoot { @Override publicvoidloadInto(Map<String, Class<? extends IRouteGroup>> routes) { routes.put("test", ARouter$$Group$$test.class); routes.put("yourservicegroupname", ARouter$$Group$$yourservicegroupname.class); } }
publicclassRouteMeta { private RouteType type; // Type of route private Element rawType; // Raw type of route private Class<?> destination; // Destination private String path; // Path of route private String group; // Group of route privateintpriority= -1; // The smaller the number, the higher the priority privateint extra; // Extra data private Map<String, Integer> paramsType; // Param type private String name;
/** * 截取跳转路径中的第一段作为分组名 */ private String extractGroup(String path) { if (TextUtils.isEmpty(path) || !path.startsWith("/")) { thrownewHandlerException(Consts.TAG + "Extract the default group failed, the path must be start with '/' and contain more than 2 '/'!"); }
try { StringdefaultGroup= path.substring(1, path.indexOf("/", 1)); if (TextUtils.isEmpty(defaultGroup)) { thrownewHandlerException(Consts.TAG + "Extract the default group failed! There's nothing between 2 '/'!"); } else { return defaultGroup; } } catch (Exception e) { logger.warning(Consts.TAG, "Failed to extract default group! " + e.getMessage()); returnnull; } }
protected Object navigation(final Context context, final Postcard postcard, finalint requestCode, final NavigationCallback callback) { try { // 将 postcard 与路由表中进行匹配,并且填充 postcard 的数据 LogisticsCenter.completion(postcard); } catch (NoRouteFoundException ex) { logger.warning(Consts.TAG, ex.getMessage()); // 如果 debug ,就显示匹配错误 if (debuggable()) { // Show friendly tips for user. runInMainThread(newRunnable() { @Override publicvoidrun() { Toast.makeText(mContext, "There's no route matched!\n" + " Path = [" + postcard.getPath() + "]\n" + " Group = [" + postcard.getGroup() + "]", Toast.LENGTH_LONG).show(); } }); } // 回调路由匹配失败 if (null != callback) { callback.onLost(postcard); } else { // No callback for this invoke, then we use the global degrade service. // 如果没有回调,就调用全局降级的策略 DegradeServicedegradeService= ARouter.getInstance().navigation(DegradeService.class); if (null != degradeService) { degradeService.onLost(context, postcard); } }
returnnull; }
// 回调路由匹配成功 if (null != callback) { callback.onFound(postcard); } // 如果不是绿色通道,就调用拦截器,拦截器这部分后面单独出来讲,这里就不讲了 if (!postcard.isGreenChannel()) { // It must be run in async thread, maybe interceptor cost too mush time made ANR. interceptorService.doInterceptions(postcard, newInterceptorCallback() { /** * Continue process * * @param postcard route meta */ @Override publicvoidonContinue(Postcard postcard) { _navigation(context, postcard, requestCode, callback); }
/** * Interrupt process, pipeline will be destory when this method called. * * @param exception Reson of interrupt. */ @Override publicvoidonInterrupt(Throwable exception) { if (null != callback) { callback.onInterrupt(postcard); }
// Set flags. intflags= 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); }
// Set Actions Stringaction= postcard.getAction(); if (!TextUtils.isEmpty(action)) { intent.setAction(action); }
// Navigation in main looper. runInMainThread(newRunnable() { @Override publicvoidrun() { startActivity(requestCode, currentContext, intent, postcard, callback); } });
break; case PROVIDER: // 如果是服务组件,那么直接返回该组件 return postcard.getProvider(); case BOARDCAST: case CONTENT_PROVIDER: case FRAGMENT: // 如果是 fragment 的话,返回该 fragment 的实例 ClassfragmentMeta= postcard.getDestination(); try { Objectinstance= fragmentMeta.getConstructor().newInstance(); if (instance instanceof Fragment) { ((Fragment) instance).setArguments(postcard.getExtras()); } elseif (instance instanceof android.support.v4.app.Fragment) { ((android.support.v4.app.Fragment) instance).setArguments(postcard.getExtras()); }
return instance; } catch (Exception ex) { logger.error(Consts.TAG, "Fetch fragment instance error, " + TextUtils.formatStackTrace(ex.getStackTrace())); } case METHOD: case SERVICE: default: returnnull; }
publicsynchronizedstaticvoidcompletion(Postcard postcard) { if (null == postcard) { thrownewNoRouteFoundException(TAG + "No postcard!"); } // 先根据 path 去获取 RouteMeta RouteMetarouteMeta= Warehouse.routes.get(postcard.getPath()); if (null == routeMeta) { // 如果 routeMeta 为空,可能是不存在或者是未加载 Class<? extendsIRouteGroup> groupMeta = Warehouse.groupsIndex.get(postcard.getGroup()); // 加载分组下的路由映射 // 如果不存在,就报错 if (null == groupMeta) { thrownewNoRouteFoundException(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 { if (ARouter.debuggable()) { logger.debug(TAG, String.format(Locale.getDefault(), "The group [%s] starts loading, trigger by [%s]", postcard.getGroup(), postcard.getPath())); } // 实现按需加载 IRouteGroupiGroupInstance= groupMeta.getConstructor().newInstance(); iGroupInstance.loadInto(Warehouse.routes); // 移除 groupsIndex , 否则会造成死循环 Warehouse.groupsIndex.remove(postcard.getGroup());
if (ARouter.debuggable()) { logger.debug(TAG, String.format(Locale.getDefault(), "The group [%s] has already been loaded, trigger by [%s]", postcard.getGroup(), postcard.getPath())); } } catch (Exception e) { thrownewHandlerException(TAG + "Fatal exception when loading group meta. [" + e.getMessage() + "]"); } // 重新加载一遍 completion(postcard); // Reload } } else { // 找到对应的 routeMeta, 填充 postcard 数据 postcard.setDestination(routeMeta.getDestination()); postcard.setType(routeMeta.getType()); postcard.setPriority(routeMeta.getPriority()); postcard.setExtra(routeMeta.getExtra());
UrirawUri= postcard.getUri(); // 如果 rawUri 不为空,则是 uri 跳转。就解析 rawUri 中的参数,放入 bundle 中 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(newString[]{})); }
// Save raw uri postcard.withString(ARouter.RAW_URI, rawUri.toString()); } // 如果是 PROVIDER 和 FRAGMENT 类型的,开启绿色通道 switch (routeMeta.getType()) { case PROVIDER: // if the route is provider, should find its instance // Its provider, so it must implement IProvider Class<? extendsIProvider> providerMeta = (Class<? extendsIProvider>) routeMeta.getDestination(); IProviderinstance= 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) { thrownewHandlerException("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; } } }
// 如果VM已经支持了MultiDex,就不要去Secondary Folder加载 Classesx.zip了,那里已经么有了 // 通过是否存在sp中的multidex.version是不准确的,因为从低版本升级上来的用户,是包含这个sp配置的 if (!isVMMultidexCapable()) { //the total dex numbers inttotalDexNumber= getMultiDexPreferences(context).getInt(KEY_DEX_NUMBER, 1); FiledexDir=newFile(applicationInfo.dataDir, SECONDARY_FOLDER_NAME);
for (intsecondaryNumber=2; secondaryNumber <= totalDexNumber; secondaryNumber++) { //for each dex file, ie: test.classes2.zip, test.classes3.zip... StringfileName= extractedFilePrefix + secondaryNumber + EXTRACTED_SUFFIX; FileextractedFile=newFile(dexDir, fileName); if (extractedFile.isFile()) { sourcePaths.add(extractedFile.getAbsolutePath()); //we ignore the verify zip part } else { thrownewIOException("Missing extracted secondary dex file '" + extractedFile.getPath() + "'"); } } }
// 如果是debug的,那么额外去加载下 instant run 中的dex文件路径 if (ARouter.debuggable()) { // Search instant run support only debuggable sourcePaths.addAll(tryLoadInstantRunDexFile(applicationInfo)); } return sourcePaths; }