Arouter源码分析之页面跳转

ARouter.getInstance()
       .build("/main/LogoutActivity")
       .navigation();
ARouter.getInstance()
public static ARouter getInstance() {
        if (!hasInit) {
            throw new InitException("ARouter::Init::Invoke init(context) first!");
        } else {
            if (instance == null) {
                synchronized (ARouter.class) {
                    if (instance == null) {
                        instance = new ARouter();
                    }
                }
            }
            return instance;
        }
    }

用双检测模式得到一个ARouter实例。

ARouter # build()
public Postcard build(String path) {
    return _ARouter.getInstance().build(path);
}
protected Postcard build(String path) {
        if (TextUtils.isEmpty(path)) {
            throw new HandlerException(Consts.TAG + "Parameter is invalid!");
        } else {
            PathReplaceService pService = ARouter.getInstance().navigation(PathReplaceService.class);
            if (null != pService) {
                path = pService.forString(path);
            }
            return build(path, extractGroup(path));
        }
    }
    
    protected Postcard build(String path, String group) {
        if (TextUtils.isEmpty(path) || TextUtils.isEmpty(group)) {
            throw new HandlerException(Consts.TAG + "Parameter is invalid!");
        } else {
            PathReplaceService pService = ARouter.getInstance().navigation(PathReplaceService.class);
            if (null != pService) {
                path = pService.forString(path);
            }
            return new Postcard(path, group);
        }
    }

ARouter# build() 返回的是一个Postcard对象

当前返回的Postcard对象携带 path和group两个路由地址数据

Postcard # navigation()

navigation()有多个构造方法,最终调的是

public Object navigation(Context mContext, Postcard postcard, int requestCode, NavigationCallback callback) {
        return _ARouter.getInstance().navigation(mContext, postcard, requestCode, callback);
    }
    
 
_ARouter # navigation()
protected Object navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
        PretreatmentService pretreatmentService = ARouter.getInstance().navigation(PretreatmentService.class);
        if (null != pretreatmentService && !pretreatmentService.onPretreatment(context, postcard)) {
            // Pretreatment failed, navigation canceled.
            return null;
        }

        try {
        // 分析1:
            LogisticsCenter.completion(postcard);
        } catch (NoRouteFoundException ex) {
            return null;
        }

        if (null != callback) {
            callback.onFound(postcard);
        }

        //针对Fragment或者Provider类型的 不会走拦截器的逻辑
        // 默认不是绿色通道
        if (!postcard.isGreenChannel()) {   // It must be run in async thread, maybe interceptor cost too mush time made ANR.
            interceptorService.doInterceptions(postcard, new InterceptorCallback() {
             
                @Override
                public void onContinue(Postcard postcard) {
                // ---------> 分析2:
                    _navigation(context, postcard, requestCode, callback);
                }

                @Override
                public void onInterrupt(Throwable exception) {
                    if (null != callback) {
                        callback.onInterrupt(postcard);
                    }
                }
            });
        } else {
            //--------> 分析2:直接进行跳转了
            return _navigation(context, postcard, requestCode, callback);
        }

        return null;
    }
LogisticsCenter.completion(postcard);
public synchronized static void completion(Postcard postcard) {
        //校验 postcard
        if (null == postcard) {
            throw new NoRouteFoundException(TAG + "No postcard!");
        }
        
        // postcard.getPath() ----> "/main/login"
        // 从仓库的路由地址清单列表中拿到对应的RouteMeta
        RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath());
        // 如果获取到的为null,说明当前路由地址清单没有被加载
        if (null == routeMeta) {    
            // 根据一级地址,拿到对应的路由地址清单的文件类(ARouter$$Root$$工程名)
            Class groupMeta = Warehouse.groupsIndex.get(postcard.getGroup());  // Load route meta.
            // 如果获取到的当前路由地址清单文件类不存在。就抛出一个异常
            if (null == groupMeta) {
                throw new NoRouteFoundException(TAG + "There is no route match the path [" + postcard.getPath() + "], in group [" + postcard.getGroup() + "]");
            } else {
                try {
                    if (ARouter.debuggable()) {
                        logger.debug(TAG, String.format(Locale.getDefault(), "The group [%s] starts loading, trigger by [%s]", postcard.getGroup(), postcard.getPath()));
                    }
                    
                    // 通过反射拿到路由地址清单文件类
                    IRouteGroup iGroupInstance = groupMeta.getConstructor().newInstance();
                    // 调用loadInto(),传入Warehouse.routes,装载路由地址清单数据
                    iGroupInstance.loadInto(Warehouse.routes);
                    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) {
                    throw new HandlerException(TAG + "Fatal exception when loading group meta. [" + e.getMessage() + "]");
                }
                // 重新调用一下自己,
                completion(postcard);   // Reload
            }
        } else {
        // 当从路由地址清单文件中找到当前路由地址对应的RouteMeta,就进行Postcard的数据填充。
            // routeMeta.getDestination() ------> 获取到的是 目标类的 Class对象
            postcard.setDestination(routeMeta.getDestination());
            // routeMeta.getType() ---> 目标类的类别 (Activity ,Fragment,Provider,Interceptor)
            postcard.setType(routeMeta.getType());
            //当前的优先级
            postcard.setPriority(routeMeta.getPriority());
            //携带的数据Bundle
            postcard.setExtra(routeMeta.getExtra());

            Uri rawUri = postcard.getUri();
            if (null != rawUri) {   // Try to set params into bundle.
                Map resultMap = TextUtils.splitQueryParameters(rawUri);
                Map paramsType = routeMeta.getParamsType();

                if (MapUtils.isNotEmpty(paramsType)) {
                    // Set value by its type, just for params which annotation by @Param
                    for (Map.Entry 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()) {
                // 是provider类型的目标类必须实现IProvider的接口
                case PROVIDER:  
                    
                    //获取provider目标类的Class对象
                    Class providerMeta = (Class) 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());
                        }
                    }
                    // 当是provider类型的时候,把获取到的目标类的实例设置到Postcard中,
                    postcard.setProvider(instance);
                    // 设置是绿色通道 ---> 所谓的绿色的通道就是不用去执行拦截器的逻辑
                    postcard.greenChannel();    
                    break;
                case FRAGMENT:
                    //同样是fragment类别的 也是绿色通道的
                    postcard.greenChannel();    
                default:
                    break;
            }
        }
    }
_navigation()
private Object _navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
        final Context currentContext = null == context ? mContext : context;

        switch (postcard.getType()) {
            //如果是ACTIVITY类型
            case ACTIVITY:
                // Build intent
                // postcard.getDestination() ---> 获取到的是目标类
                //进行Intent的拼装
                final Intent intent = new Intent(currentContext, postcard.getDestination());
                intent.putExtras(postcard.getExtras());

                // 设置falg信息
                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);
                }

                // 设置Action的信息
                String action = postcard.getAction();
                if (!TextUtils.isEmpty(action)) {
                    intent.setAction(action);
                }

                runInMainThread(new Runnable() {
                    @Override
                    public void run() {
                    // 因为正常的页面跳转 在跳转钱都会执行拦截器的操作,为拦截器的执行是在线程池中
                    // 对应的回调也运行在工作线程中
                    // 调用startActivity()方法,发起页面跳转的请求
                        startActivity(requestCode, currentContext, intent, postcard, callback);
                    }
                });

                break;
            case PROVIDER:
            // 是provider类型,就返回Provider实现子类的对象
                return postcard.getProvider();
            case BOARDCAST:
            case CONTENT_PROVIDER:
            case FRAGMENT:
                Class fragmentMeta = postcard.getDestination();
                try {
                    Object instance = fragmentMeta.getConstructor().newInstance();
                    //如果手Fragment类型
                    // 把要传递到Fragment中的数据 设置给当前的Fragmenrt
                    if (instance instanceof Fragment) {
                        ((Fragment) instance).setArguments(postcard.getExtras());
                    } else if (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:
                return null;
        }

        return null;
    }

你可能感兴趣的:(Arouter源码分析之页面跳转)