Arouter源码分析

编译期:

在每个module下包括app下,build文件夹com.alibaba.android.arouter.routes包下

a、生成Arouter¥¥Root¥¥(ModuleName)

比如:app下生成Arouter¥¥Root¥¥app
module-java下生成Arouter¥¥Roo¥¥modulejava

//维护所有的Group
public class ARouter$$Root$$app implements IRouteRoot {
  @Override
  public void loadInto(Map<String, Class<? extends IRouteGroup>> routes) {
    routes.put("mydegraytest", ARouter$$Group$$mydegraytest.class);
    routes.put("test", ARouter$$Group$$test.class);
    routes.put("yourservicegroupname", ARouter$$Group$$yourservicegroupname.class);
  }
}

根据group生成Arouter¥¥Group¥¥(GroupName)
比如名为test的group生成Arouter¥¥Group¥¥test

//维护所有的RouteMeta
            public class ARouter$$Group$$test implements IRouteGroup {
              @Override
              public void loadInto(Map<String, RouteMeta> atlas) {
                atlas.put("/test/activity1", RouteMeta.build(RouteType.ACTIVITY, Test1Activity.class, "/test/activity1", "test", new java.util.HashMap<String, Integer>(){{put("ser", 9); put("ch", 5); put("fl", 6); put("dou", 7); put("boy", 0); put("url", 8); put("pac", 10); put("obj", 11); put("name", 8); put("objList", 11); put("map", 11); put("age", 3); put("height", 3); }}, -1, -2147483648));
                atlas.put("/test/activity2", RouteMeta.build(RouteType.ACTIVITY, Test2Activity.class, "/test/activity2", "test", new java.util.HashMap<String, Integer>(){{put("key1", 8); }}, -1, -2147483648));
                atlas.put("/test/activity3", RouteMeta.build(RouteType.ACTIVITY, Test3Activity.class, "/test/activity3", "test", new java.util.HashMap<String, Integer>(){{put("name", 8); put("boy", 0); put("age", 3); }}, -1, -2147483648));
                atlas.put("/test/activity4", RouteMeta.build(RouteType.ACTIVITY, Test4Activity.class, "/test/activity4", "test", null, -1, -2147483648));
                atlas.put("/test/fragment", RouteMeta.build(RouteType.FRAGMENT, BlankFragment.class, "/test/fragment", "test", null, -1, -2147483648));
                atlas.put("/test/webview", RouteMeta.build(RouteType.ACTIVITY, TestWebview.class, "/test/webview", "test", null, -1, -2147483648));
              }
            }
b、生成Arouter¥¥Providers¥¥(ModuleName)
//维护所有的providers,包装进RouteMeta
public class ARouter$$Providers$$app implements IProviderGroup {
      @Override
      public void loadInto(Map<String, RouteMeta> providers) {
        providers.put("com.alibaba.android.arouter.facade.service.DegradeService", RouteMeta.build(RouteType.PROVIDER, DegradeServiceImpl.class, "/mydegraytest/degray", "mydegraytest", null, -1, -2147483648));
        providers.put("com.alibaba.android.arouter.demo.testservice.HelloService", RouteMeta.build(RouteType.PROVIDER, HelloServiceImpl.class, "/yourservicegroupname/hello", "yourservicegroupname", null, -1, -2147483648));
        providers.put("com.alibaba.android.arouter.facade.service.SerializationService", RouteMeta.build(RouteType.PROVIDER, JsonServiceImpl.class, "/yourservicegroupname/json", "yourservicegroupname", null, -1, -2147483648));
        providers.put("com.alibaba.android.arouter.demo.testservice.SingleService", RouteMeta.build(RouteType.PROVIDER, SingleService.class, "/yourservicegroupname/single", "yourservicegroupname", null, -1, -2147483648));
      }
    }
c、生成Arouter¥¥Interceptors¥¥(ModuleName)
//维护所有的interceptors
public class ARouter$$Interceptors$$app implements IInterceptorGroup {
      @Override
      public void loadInto(Map<Integer, Class<? extends IInterceptor>> interceptors) {
      interceptors.put(7, Test1Interceptor.class);
      }
}
运行期:
初始化操作
init()
public synchronized static void init(Context context, ThreadPoolExecutor tpe) throws HandlerException {
       ...
 routerMap = ClassUtils.getFileNameByPackageName(mContext, ROUTE_ROOT_PAKCAGE);
   ...
	for (String className : routerMap) {
	    if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_ROOT)) {
	        // This one of root elements, load root.
	        ((IRouteRoot) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.groupsIndex);
	    } else if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_INTERCEPTORS)) {
	        // Load interceptorMeta
	        ((IInterceptorGroup) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.interceptorsIndex);
	    } else if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_PROVIDERS)) {
	        // Load providerIndex
	        ((IProviderGroup) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.providersIndex);
	    }
	}
}
...

扫描所有以com.alibaba.android.arouter.routes为包名的class文件,并进行分组,
分别保存到Warehouse.groupsIndex;Warehouse.interceptorsIndex;Warehouse.providersIndex
Arouter的path有两个路径,group,path;
1、在IRouteRoot中初始化,Warehouse.groupsIndex,以group为key,保存所有的IRouteGroup;
 a、主要包括arouterapi组,如route–ARouter¥¥Group¥¥arouter;
 b、当前项目app中的自定义组,如
   test–ARouter¥¥Group¥¥test,
   yourservicegroupname–ARouter¥¥Group¥¥yourservicegroupname,
   mydegraytest–ARouter¥¥Group¥¥mydegraytest
2、在IInterceptorGroup中初始化,Warehouse.interceptorsIndex,以priority为key,保存所有的Interceptor;
3、在IProviderGroup中初始化,Warehouse.providersIndex,以class全路径名为key,保存Provider类型的RouteMeta;
 a、主要包括arouterapi组,如
   com.alibaba.android.arouter.facade.service.AutowiredService–RouteMeta.build(RouteType.PROVIDER, AutowiredServiceImpl.class, “/arouter/service/autowired”, “arouter”, null, -1, -2147483648);
   com.alibaba.android.arouter.facade.service.InterceptorService–RouteMeta.build(RouteType.PROVIDER, InterceptorServiceImpl.class, “/arouter/service/interceptor”, “arouter”, null, -1, -2147483648)
 b、当前项目app中的自定义组,如
   com.alibaba.android.arouter.facade.service.SerializationService–RouteMeta.build(RouteType.PROVIDER,JsonServiceImpl.class,"/yourservicegroupname/json", “yourservicegroupname”, null, -1, -2147483648)等等;

afterInit()
static void afterInit() {
        // Trigger interceptor init, use byName.
        interceptorService = (InterceptorService) ARouter.getInstance().build("/arouter/service/interceptor").navigation();
}

protected Postcard build(String path) {
        if (TextUtils.isEmpty(path)) {
            throw new HandlerException(Consts.TAG + "Parameter is invalid!");
        } else {
            //可以对path进行拦截,重新定义
            PathReplaceService pService = ARouter.getInstance().navigation(PathReplaceService.class);
            if (null != pService) {
                path = pService.forString(path);
            }
            return build(path, extractGroup(path));
        }
}

public synchronized static void completion(Postcard postcard) {
		...
        //根据path从routes中获取routeMeta
        RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath());
        if (null == routeMeta) {    // Maybe its does't exist, or didn't load.
            //根据group从groupIndex中加载IRouteGroup
            Class<? extends IRouteGroup> groupMeta = Warehouse.groupsIndex.get(postcard.getGroup());  // Load route meta.
            ...
	            IRouteGroup iGroupInstance = groupMeta.getConstructor().newInstance();
	            //在IRoutRoot中根据group找到对应的IRouteGroup,并以path为key,对应的RouteMeta为value存入routes
	            //比如atlas.put("/arouter/service/interceptor", RouteMeta.build(RouteType.PROVIDER, InterceptorServiceImpl.class, "/arouter/service/interceptor", "arouter", null, -1, -2147483648))
	            iGroupInstance.loadInto(Warehouse.routes);
	            Warehouse.groupsIndex.remove(postcard.getGroup());
                completion(postcard);   // Reload
            }
        } else {
            //设置目标
            postcard.setDestination(routeMeta.getDestination());
            //设置type
            postcard.setType(routeMeta.getType());
            //设置优先级
            postcard.setPriority(routeMeta.getPriority());
            //设置extra
            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()) {
                case PROVIDER:
                    //比如找到Interceptor对应的routeMeta,它的destination为InterceptorServiceImpl.class
                    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 {
                            //初始化InterceptorServiceImpl用于创建和回调Interceptors
                            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());
                        }
                    }
                    //将InterceptorServiceImpl实例化设置到postcard
                    postcard.setProvider(instance);
                    postcard.greenChannel();    // Provider should skip all of interceptors
                    break;
                case FRAGMENT:
                    postcard.greenChannel();    // Fragment needn't interceptors
                default:
                    break;
            }
        }
    }
InterceptorServiceImpl 下的init方法
@Route(path = "/arouter/service/interceptor")
public class InterceptorServiceImpl implements InterceptorService {
    ...
    @Override
    public void init(final Context context) {
        //开启线程组装interceptor集合,按照priority控制顺序
        LogisticsCenter.executor.execute(new Runnable() {
            @Override
            public void run() {
                if (MapUtils.isNotEmpty(Warehouse.interceptorsIndex)) {
                    for (Map.Entry<Integer, Class<? extends IInterceptor>> entry : Warehouse.interceptorsIndex.entrySet()) {
                        Class<? extends IInterceptor> interceptorClass = entry.getValue();
                        try {
                            IInterceptor iInterceptor = interceptorClass.getConstructor().newInstance();
                            iInterceptor.init(context);
                            Warehouse.interceptors.add(iInterceptor);
                        } catch (Exception ex) {
                            throw new HandlerException(TAG + "ARouter init interceptor error! name = [" + interceptorClass.getName() + "], reason = [" + ex.getMessage() + "]");
                        }
                    }
                    interceptorHasInit = true;
                    logger.info(TAG, "ARouter interceptors init over.");
                    // 组装完成唤醒锁
                    synchronized (interceptorInitLock) {
                        interceptorInitLock.notifyAll();
                    }
                }
            }
        });
    }
	...
}

构建InterceptorService。
1、先构建Atouter,调用build()
  将path传入,在build方法中可以自定义实现PathReplaceService,并实现其中方法,可以对patch进行拦截,并重新定义,最后构建Postcard。
2、navigation()
  会走到LogisticsCenter#completion方法,该方法中维护一个path为key,RouteMeta为value的Warehouse.routes 的hashmap集合,在Warehouse.groupsIndex 中根据group获取所有的Arouter¥¥Group¥¥arouter;并将其中的信息以path为key,RouteMeta为value存入Warehouse.routes
  再次调用completion方法,根据path将RouteMeta取出,并封装到Postcard中,这里routeMeta类型为PROVIDER,找出对应的RouteMeta,根据其中的destination,实例化InterceptorServiceImpl 并调用init方法,并将InterceptorServiceImpl 设置到Postcard的provider,设置greenChannel绕过interceptors,调用_navigation(context, postcard, requestCode, callback) 将InterceptorServiceImpl 返回。

执行一次跳转
ARouter.getInstance()
                        .build("/kotlin/test")
                        .withString("name", "老王")
                        .withInt("age", 23)
                        .navigation();
protected Object navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
        ...
        LogisticsCenter.completion(postcard);
        ...

        if (!postcard.isGreenChannel()) {   // It must be run in async thread, maybe interceptor cost too mush time made ANR.
            //如果不是绿色通道,执行interceptor
            interceptorService.doInterceptions(postcard, new InterceptorCallback() {
                @Override
                public void onContinue(Postcard postcard) {
                    _navigation(context, postcard, requestCode, callback);
                }
                
                @Override
                public void onInterrupt(Throwable exception) {
                    if (null != callback) {
                        callback.onInterrupt(postcard);
                    }
            });
        } else {
            //绿色通道
            return _navigation(context, postcard, requestCode, callback);
        }
        return null;
    }

通过build返回postcard,通过withString,withInt,将需要传递的数据放入bundle,调用navigation,逻辑同上,这里routeMeta类型为ACTIVITY,默认没有设置greenChannel,会执行interceptors:

@Route(path = "/arouter/service/interceptor")
public class InterceptorServiceImpl implements InterceptorService {
    private static boolean interceptorHasInit;
    private static final Object interceptorInitLock = new Object();

    @Override
public void doInterceptions(final Postcard postcard, final InterceptorCallback callback) {
    if (null != Warehouse.interceptors && Warehouse.interceptors.size() > 0) {
        //检查interceptor组装完成状态
        checkInterceptorsInitStatus();
        //超时会抛出异常,终止路由
        if (!interceptorHasInit) {
            callback.onInterrupt(new HandlerException("Interceptors initialization takes too much time."));
            return;
        }
        //开启多线程执行Interceptor的process方法,这里使用CountDownlatch,使当前线程等待;
        //等到所有的interceptor的process方法都执行完后,执行当前线程,默认给出300s的等待时间。
        LogisticsCenter.executor.execute(new Runnable() {
            @Override
            public void run() {
                CancelableCountDownLatch interceptorCounter = new CancelableCountDownLatch(Warehouse.interceptors.size());
                try {
                    _excute(0, interceptorCounter, postcard);
                    //执行完interceptor后,在执行后续操作
                    //如果执行完interceptor后,countDown.getCount仍不为0,在等待await的时间,默认300s的等待时间
                    //如果执行完interceptor后,countDown.getCount为0,不需要等待,直接进入后续逻辑。
                    interceptorCounter.await(postcard.getTimeout(), TimeUnit.SECONDS);
                    if (interceptorCounter.getCount() > 0) {    // Cancel the navigation this time, if it hasn't return anythings.
                        //在postcard.getTimeout()后执行后续,代表interceptor处理超时
                        callback.onInterrupt(new HandlerException("The interceptor processing timed out."));
                    } else if (null != postcard.getTag()) {    // Maybe some exception in the tag.
                        //在interceptor中调用了onInterrupt中断操作
                        callback.onInterrupt(new HandlerException(postcard.getTag().toString()));
                    } else {
                        //继续操作
                        callback.onContinue(postcard);
                    }
                } catch (Exception e) {
                    callback.onInterrupt(e);
                }
            }
        });
    } else {
        //不存在interceptor,继续操作
        callback.onContinue(postcard);
    }
}
    private static void _excute(final int index, final CancelableCountDownLatch counter, final Postcard postcard) {
        if (index < Warehouse.interceptors.size()) {
            IInterceptor iInterceptor = Warehouse.interceptors.get(index);
            iInterceptor.process(postcard, new InterceptorCallback() {
                @Override
                public void onContinue(Postcard postcard) {
                    // Last interceptor excute over with no exception.
                    counter.countDown();
                    //外部interceptor调用onContinue后,继续下一个interceptor
                    _excute(index + 1, counter, postcard);  // When counter is down, it will be execute continue ,but index bigger than interceptors size, then U know.
                }

                @Override
                public void onInterrupt(Throwable exception) {
                    //外部interceptor调用onInterrupt后,中断拦截器,并设置异常。
                    postcard.setTag(null == exception ? new HandlerException("No message.") : exception.getMessage());    // save the exception message for backup.
                    counter.cancel();
                }
            });
        }
    }

    /**
     * 等待interceptors组装完成,等待10s的时间。
     */
    private static void checkInterceptorsInitStatus() {
    //多线程组装interceptor,执行doInterceptions方法时可能还没有组装完成,申请锁,并在不满足条件的情况下执行线程等待
    //init方法中完成组装后进行notify,这里会被唤醒,或者等待10s自动唤醒。
    synchronized (interceptorInitLock) {
        while (!interceptorHasInit) {
            try {
                interceptorInitLock.wait(10 * 1000);
            } catch (InterruptedException e) {
                throw new HandlerException(TAG + "Interceptor init cost too much time error! reason = [" + e.getMessage() + "]");
            }
        }
    }
}
}

在InterceptorService的callback的onContinue回调中执行_navigation(context, postcard, requestCode, callback);:

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
            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);
            }
            // Set Actions
            String action = postcard.getAction();
            if (!TextUtils.isEmpty(action)) {
                intent.setAction(action);
            }
            // Navigation in main looper.
            runInMainThread(new Runnable() {
                @Override
                public void run() {
                    startActivity(requestCode, currentContext, intent, postcard, callback);
                }
            });
            break;
        ...
}

最终会回调startActivity或者startActivityForResult

Arouter的Inject()
 static void inject(Object thiz) {
        //实例化AutowiredService
        AutowiredService autowiredService = ((AutowiredService) ARouter.getInstance().build("/arouter/service/autowired").navigation());
            if (null != autowiredService) {
                autowiredService.autowire(thiz);
            }
        }

如同构建InterceptorService,根据path找到对应的RouteMeta,根据其中的detination实例化AutowiredServiceImpl,并调用init方法:

public class AutowiredServiceImpl implements AutowiredService {
    private LruCache<String, ISyringe> classCache;
    private List<String> blackList;

    @Override
    public void init(Context context) {
        classCache = new LruCache<>(66);
        blackList = new ArrayList<>();
    }

    /**
     * 在跳转后的页面中调用
     * @param instance the instance who need autowired.
     */
    @Override
    public void autowire(Object instance) {
        String className = instance.getClass().getName();
        try {
            if (!blackList.contains(className)) {
                ISyringe autowiredHelper = classCache.get(className);
                if (null == autowiredHelper) {  // No cache.
                    //实例化注解生成的Test1Activity$$ARouter$$Autowired
                    autowiredHelper = (ISyringe) Class.forName(instance.getClass().getName() + SUFFIX_AUTOWIRED).getConstructor().newInstance();
                }
                autowiredHelper.inject(instance);
                classCache.put(className, autowiredHelper);
            }
        } catch (Exception ex) {
            blackList.add(className);    // This instance need not autowired.
        }
    }
}

public class Test1Activity$$ARouter$$Autowired implements ISyringe {
  private SerializationService serializationService;

  @Override
  public void inject(Object target) {

    //最终会在providerIndex中根据SerializationService.class找到JsonServiceImpl并实例化返回
    serializationService = ARouter.getInstance().navigation(SerializationService.class);

    //下面的过程就是将源页面传递过来的Intent根据的key获取对应的value,并赋值到对应的成员
    Test1Activity substitute = (Test1Activity)target;
    substitute.name = substitute.getIntent().getStringExtra("name");
    ...
    substitute.ser = (com.alibaba.android.arouter.demo.testinject.TestSerializable) substitute.getIntent().getSerializableExtra("ser");
    substitute.pac = substitute.getIntent().getParcelableExtra("pac");
    if (null != serializationService) {
        //使用jsonServiceImpl解析传递过来的String转换为object
      substitute.obj = serializationService.parseObject(substitute.getIntent().getStringExtra("obj"), new com.alibaba.android.arouter.facade.model.TypeWrapper<TestObj>(){}.getType());
    } else {
      Log.e("ARouter::", "You want automatic inject the field 'obj' in class 'Test1Activity' , then you should implement 'SerializationService' to support object auto inject!");
    }
   ...
  }
}

支持解析对象,同时支持自定义的解析json方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值