前言
CC采用组件总线的方案,可以让你在对老项目进行组件化时不需要一下子拆分成一个个组件,反而这是一个渐进的过程,也就是文档所说的渐进式组件化。既然它这么优秀,那我们在使用它时,学下它的原理应该会有很多的收获。
CC的项目地址:https://github.com/luckybilly/CC
CC的文档地址:https://qibilly.com/CC-website
文中的图片出自它的文档地址。
开始
发起调用
在开始跟踪调用流程之前,我们先来看一张来自文档网站的图片:
根据图片可以知道CC的组件调用期间就是通过一系列的拦截器进行的,接下来开启它的调用流程。
在开始调用的时候,call表示同步调用,callAsync表示发起异步的调用,这两个方法会做一些参数的初始化和超时默认的设置,最终都会调用ComponentManager的call(this)方法:
static CCResult call(CC cc) {
//1.添加自定义的拦截器
chain.addInterceptors(cc.getInterceptors());
//2. 有效性校验放在自定义拦截器之后执行,优先执行自定义拦截器,让其可以拦截到所有组件调用
// 执行实际调用的拦截器在校验有效性结束后再添加
chain.addInterceptor(ValidateInterceptor.getInstance());
ChainProcessor processor = new ChainProcessor(chain);
//异步调用,放到线程池中运行
if (cc.isAsync()) {
//...
CC_THREAD_POOL.submit(processor);
//异步调用时此方法返回null,CCResult通过callback回调
return null;
} else {
//同步调用,直接执行
ccResult = processor.call();
}
//同步调用的返回结果,永不为null,默认为CCResult.defaultNullResult()
return ccResult;
}
}
ComponentManager.call(cc)方法的核心操作已经在注释了。
接下来看看ChainProcessor的call方法是什么操作:
public CCResult call() throws Exception {
//...
//从开始调用的时候就开始进行监控,也许时间设置的很短,可能都不需要执行拦截器调用链
CCMonitor.addMonitorFor(cc);
CCResult result;
try {
//开启一系列的拦截器操作
result = chain.proceed();
} finally {
CCMonitor.removeById(callId);
}
//...
return result;
}
可以看到首先将CC对象添加到一个监控中,然后开始启动拦截链的调用,也就是执行逐个添加进去的拦截器,最后将CC对象从监控中移除,关于监控的作用后边会讲到。
chain.proceed():开始拦截器链的链式调用,它会逐个调用,首先会调用用户设置的拦截器,其次是刚才添加进去的ValidateInterceptor
ValidateInterceptor: 检查cc的合法性
- 判断是否是当前进程的组件,是的话添加LocalCCInterceptor
- 在本app(主进程和子进程)中找不到组件,则添加RemoteCCInterceptor
- 否则在app内部子进程的组件,添加SubProcessCCInterceptor
- 最后添加Wait4ResultInterceptor
public CCResult intercept(Chain chain) {
//省略一系列的检查:大致如下
/**
1. 没有指定要调用的组件名称,中止运行
2. context为null (没有设置context 且 CC中获取application失败)
3. 当前进程中不包含此组件,查看一下其它进程中是否包含此组件
4. 本app内所有进程均没有指定的组件,并且设置了不会调用外部app的组件
*/
//...
//执行完自定义拦截器,并且通过有效性校验后,再确定具体调用组件的方式
if (ComponentManager.hasComponent(componentName)) {
//调用当前进程中的组件
chain.addInterceptor(LocalCCInterceptor.getInstance());
} else {
if (notFoundInCurApp == null) {
notFoundInCurApp = TextUtils.isEmpty(ComponentManager.getComponentProcessName(componentName));
}
if (notFoundInCurApp) {
//调用设备上安装的其它app(组件单独运行的app)中的组件
chain.addInterceptor(RemoteCCInterceptor.getInstance());
} else {
//调用app内部子进程中的组件
chain.addInterceptor(SubProcessCCInterceptor.getInstance());
}
}
//添加最后的Wait4ResultInterceptor拦截器,用来等待结果的发送。
chain.addInterceptor(Wait4ResultInterceptor.