美文网首页
Arouter源码阅读

Arouter源码阅读

作者: 河里的枇杷树 | 来源:发表于2019-01-11 15:21 被阅读7次

    自己的阅读笔记

    一.从ARouter.init(context);方法开始看,

    1. LogisticsCenter.init()方法,起作用是将 arouter-compiler生成的类解析,存储到sp中并且加载到内存中备用
      • 遍历所有dex 拿到 com.alibaba.android.arouter.routes 包下的所有类,存放到 Set 集合routerMap中,并将routerMap集合存放到Sp中

      • 遍历routerMap集合 将集合内容分为 Root Interceptors Providers三类分别将这三类中的内容存储到 Warehouse中的集合中备用

    2. _ARouter.afterInit()方法将拦截器服务启动。以后调用navigation()方法都会出发拦截器(绿色通道除外)

    二.ARouter.getInstance().build(url).navigation();从这个链式调用开始看

    1. 看看build(url)干了什么?
      这个方法干的事儿比较简单,只是通过传入的url确定了group,并返回一个 Postcard

    2. Postcard的navigation();方法其实又调用到了_ARouter的navigation方法

      • _ARouter的navigation方法中首先通过LogisticsCenter.completion(postcard);方法将url对应的RouteMeta(路由数据)设置到Postcard
      • 判断该次调用是否是绿色通道(绿色通道的话会跳过所有拦截器
      • Postcard不同的type做不同的操作,type都包含ACTIVITY,PROVIDER,BOARDCASTCONTENT_PROVIDER,FRAGMENT,METHOD,SERVICE

    3.看看当type是ACTIVITY的时候回是怎么调到对应的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());
                            }
    
                            if (null != callback) { // Navigation over.
                                callback.onArrival(postcard);
                            }
                        }
                    });
    

    可以看出来Arouter底层也是通过显示调用Activity的

    4.看看当type是PROVIDER的时候回是怎么实例化Provider的

                        // Its provider, so it must be implememt 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) {
                                throw new HandlerException("Init provider failed! " + e.getMessage());
                            }
                        }
                        postcard.setProvider(instance);
                        postcard.greenChannel();    // Provider should skip all of interceptors
    

    可以看出来当是Provider的时候直接用反射创建实例的

    相关文章

      网友评论

          本文标题:Arouter源码阅读

          本文链接:https://www.haomeiwen.com/subject/tklidftx.html