一、简介
ARouter是一个路由框架,主要用于解决模块化场景后的模块间通信问题而设计的
ARouter的优势:
- 优势一:直接解析URL路由,解析参数并赋值到对应目标字段的页面中。
- 优势二:支持多模块项目,因为现在很少有APP是单模块的项目,一般都是多模块单工程的,由不同的团队负责不同的模块开发,这时候支持多模块项目开发就显得尤为重要。
- 优势三:支持InstantRun,目前很多路由框架并不支持InstantRun,而InstantRun是Google在AndroidStudio2.0阿尔法版本中提供的新功能,其类似于代码的日更新,其只不过面向的是开发过程,这样做可以在开发的过程中减少开发和编译的次数,可以简单地将代码修改即时地同步到APK中,从而可以大规模降低开发复杂度。
- 优势四:允许自定义拦截器,ARouter是支持拦截器的,而拦截器其实就是AOP的实现,可以自定义多个拦截器解决一些面向行为编程上出现的问题。
- 优势五:ARouter可以提供IoC容器,IoC其实就是控制反转,这一部分做过服务端开发的朋友可能比较了解,因为服务端开发经常用到的Spring框架能够提供的一个非常重要的能力就是控制反转。
- 优势六:映射关系自动注册,在页面不是很多的小型APP上面,自动注册并不会体现出太大优势,但是对于大型APP而言,可能页面数量已经达到的几十个或者数百个,在这样的情况下,自动注册就显得非常重要了,因为不可能将每一个页面都通过代码的方式进行注册。
- 优势七:灵活的降级策略,ARouter可以提供很多种降级策略供用户自行选择,而原生的路由方案存在无法灵活降级的问题,StartActivity()一旦失败将会抛出运营级异常。
二、整体流程图
三、概念解释
RouteMeta:路由元信息,即基础信息。理解就是 明信片上的 收件人地址 这种必备的基础信息。明信片上可以没有文字内容,但想要被邮寄就必须有收件人地址。
Postcard:路由的信息。理解为是生活中的明信片。继承自RouteMeta。例如Postcard中的mBundle等则是 明信片上寄件人写的 “你好,xxx 节日快乐!” 这种文字内容。
WareHorse:信息中心,各类路由信息的存储中心。
四、流程
Postcard postcard = ARouter.getInstance().build(AppRouter.LauncherActivity.PATH);
postcard.navigation(context);
整体流程就分为两步:
获取postcard:
-
-
前置拦截处理:PathReplaceService,看看是否需要变换路由地址,不需要就创建一个postcard
-
完善postcard信息:通过LogisticsCenter.completion方法,获取RouteMeta完善postcard信息(分组加载:获取RouteMeta,不存在时,说明该组第一次使用,此时将组加载到Warehouse.routes中去)
-
后置绿色通道处理:provider、fragment 默认会走绿色通道,正常其他的路由,需要走非绿色通过逻辑,提供一次拦截能力
-
使用postcard去路由:例如进行目标Activity的跳转、获取IProvider实现对象、获取Fragment等。
五、核心代码
可见,postcard 经过完善后,路由类型type、目的地destination等都已经被赋了值。destination就是目标类的class对象。
方法内容就是根据路由类型来走对应逻辑:
- Activity, 使用postcard.getDestination()来构建intent、传入Extras、设置 flags、action,最后在主线程执行 熟悉的startActivity
- provider,指的是想要获取的服务,即IProvider的实现类。是直接从postCard中获取的,因为服务类是单例,只会在首次获取时创建()。
- Broadcast、ContentProvider、Fragment,都是使用postcard.getDestination()反射创建实例
private Object _navigation(final Postcard postcard, final int requestCode, final NavigationCallback callback) {
final Context currentContext = postcard.getContext();
switch (postcard.getType()) {
case ACTIVITY:
final Intent intent = new Intent(currentContext, postcard.getDestination());
intent.putExtras(postcard.getExtras());
int flags = postcard.getFlags();
if (0 != flags) {
intent.setFlags(flags);
}
if (!(currentContext instanceof Activity)) {
intent.addFlags(268435456);
}
String action = postcard.getAction();
if (!TextUtils.isEmpty(action)) {
intent.setAction(action);
}
this.runInMainThread(new Runnable() {
public void run() {
_ARouter.this.startActivity(requestCode, currentContext, intent, postcard, callback);
}
});
return null;
case PROVIDER:
return postcard.getProvider();
case BOARDCAST:
case CONTENT_PROVIDER:
case FRAGMENT:
Class<?> fragmentMeta = postcard.getDestination();
try {
Object instance = fragmentMeta.getConstructor().newInstance();
if (instance instanceof Fragment) {
((Fragment)instance).setArguments(postcard.getExtras());
} else if (instance instanceof androidx.fragment.app.Fragment) {
((androidx.fragment.app.Fragment)instance).setArguments(postcard.getExtras());
}
return instance;
} catch (Exception var10) {
logger.error("ARouter::", "Fetch fragment instance error, " + TextUtils.formatStackTrace(var10.getStackTrace()));
}
case METHOD:
case SERVICE:
default:
return null;
}
}
附件:
ARouter完全解析:cloud.tencent.com/developer/a…
ARouter官方使用文档:github.com/alibaba/ARo…