ARouter源码解析

ARouter源码解析

0x01 init ()

ARouter 的入口,初始化SDK ARouter.init(mApplication);

1
2
3
4
5
6
7
8
9
10
11
public static void init(Application application) {
if (!hasInit) { // 避免重复初始化
logger = _ARouter.logger; // 日志初始化
_ARouter.logger.info(Consts.TAG, "ARouter init start.");
hasInit = _ARouter.init(application); // 正式初始化
if (hasInit) { // 初始化之后
_ARouter.afterInit(); // 管理拦截器的服务 InterceptorService 初始化
}
_ARouter.logger.info(Consts.TAG, "ARouter init over.");
}
}

_ARouter.init()

1
2
3
4
5
6
7
8
protected static synchronized boolean init(Application application) {
mContext = application; // 初始化application
LogisticsCenter.init(mContext, executor); // 指定默认的线程池初始化
logger.info(Consts.TAG, "ARouter init success!");
hasInit = true;// 初始化成功
mHandler = new Handler(Looper.getMainLooper());// 初始化mHandler
return true;
}

LogisticsCenter.init()

1 使用 arouter-auto-register 插件自动加载 routerMap

2 手动加载的情况,release 仅第一次会去解析 routerMap,其他时候都读取 SharedPreferences

3 根据routerMap三种类型,分别缓存在Warehouse 的Map中

  • route and metas
  • provider
  • interceptor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// LogisticsCenter init, load all metas in memory.
public synchronized static void init(Context context, ThreadPoolExecutor tpe) throws HandlerException {
mContext = context;
executor = tpe; // 线程池
//...
loadRouterMap(); // 插件arouter-auto-register会生成这个方法的代码实现
if (registerByPlugin) {
logger.info(TAG, "Load router map by arouter-auto-register plugin.");
} else {// 不用插件手动加载routerMap
Set<String> routerMap; // routerMap
// Debug 模式每次更新 routerMap,并更新SharedPreferences
if (ARouter.debuggable() || PackageUtils.isNewVersion(context)) {
routerMap = ClassUtils.getFileNameByPackageName(mContext, ROUTE_ROOT_PAKCAGE);
if (!routerMap.isEmpty()) {
context.getSharedPreferences(AROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).edit().putStringSet(AROUTER_SP_KEY_MAP, routerMap).apply();
}
PackageUtils.updateVersion(context);
} else {
// 直接从 SharedPreferences 读取 routerMap
routerMap = new HashSet<>(context.getSharedPreferences(AROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).getStringSet(AROUTER_SP_KEY_MAP, new HashSet<String>()));
}
//...
for (String className : routerMap) {
if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_ROOT)) {
// 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);
}
}
}
//...
}

class Warehouse 缓存三种类型的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Warehouse {
// Cache route and metas
static Map<String, Class<? extends IRouteGroup>> groupsIndex = new HashMap<>();
static Map<String, RouteMeta> routes = new HashMap<>();

// Cache provider
static Map<Class, IProvider> providers = new HashMap<>();
static Map<String, RouteMeta> providersIndex = new HashMap<>();

// Cache interceptor
static Map<Integer, Class<? extends IInterceptor>> interceptorsIndex = new UniqueKeyTreeMap<>("More than one interceptors use same priority [%s]");
static List<IInterceptor> interceptors = new ArrayList<>();
}

总结来说,init过程就是把所有注解的信息加载内存中,并且完成所有拦截器的初始化。

0x02 navigation()

发起路由操作 ARouter.getInstance().build("/test/activity").navigation();

1
2
3
public Postcard build(String path) {
return _ARouter.getInstance().build(path);
}

都是单例设计,最后调用 _ARouter 单例的 build()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
protected Postcard build(String path) {
//...
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) {
//...
PathReplaceService pService = ARouter.getInstance().navigation(PathReplaceService.class);
if (null != pService) {
path = pService.forString(path);
}
return new Postcard(path, group);
}

PathReplaceService,它是继承IProvider的接口,它是预留给用户实现路径动态变化功能。

Postcard 是一个继承自 RouteMeta 的数据 Bean。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public final class Postcard extends RouteMeta {
// Base
private Uri uri;
private Object tag; // A tag prepare for some thing wrong.
private Bundle mBundle; // Data to transform
private int flags = -1; // Flags of route
private int timeout = 300; // Navigation timeout, TimeUnit.Second
private IProvider provider; // It will be set value, if this postcard was provider.
private boolean greenChannel;
private SerializationService serializationService;

// Animation
private Bundle optionsCompat; // The transition animation of activity
private int enterAnim = -1;
private int exitAnim = -1;
//...
}

Postcard 对象的 navigation 方法,最终还是调用的 _Arouternavigation方法。

1 PretreatmentService 进行跳转的拦截和检测

2 LogisticsCenter.completion(postcard) Postcard 加载和自解析

3 Postcard 解析异常 回调 callback.onLost,若 callback 为空则 DegradeService 降级回调处理

4 Postcard 处理结束,回调 callback.onFound(postcard)

5 GreenChannel 的 navigation,直接执行 _navigation 路由

6 非 GreenChannel 的 navigation,异步执行注入拦截器。拦截之后回调 callback.onInterrupt, 通过所有的拦截器,则继续执行 _navigation 路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
protected Object navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
PretreatmentService pretreatmentService = ARouter.getInstance().navigation(PretreatmentService.class);
// ....pretreatmentService拦截
try {
LogisticsCenter.completion(postcard);// postcard 自解析
} catch (NoRouteFoundException ex) {
// ....
if (null != callback) {
callback.onLost(postcard);
} else {
// No callback for this invoke, then we use the global degrade service.
DegradeService degradeService = ARouter.getInstance().navigation(DegradeService.class);
if (null != degradeService) {
degradeService.onLost(context, postcard);
}
}
return null;
}

if (null != callback) {
callback.onFound(postcard); // Postcard 处理结束,回调 callback.onFound(postcard)
}

if (!postcard.isGreenChannel()) {
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;
}

_Arouter_navigation 方法

1 根据 postcard.getType() 处理

2 ACTIVITY 类型, 根据 postcard.getDestination() 生成一个 intent,然后 putExtras, 并设置对应的 flag 和 action 执行跳转

3 PROVIDER 类型,直接返回在 LogisticsCenter.completion(postcard) 生成的 IProvider 实例

4 BOARDCAST,CONTENT_PROVIDER,FRAGMENT 类型分别返回 newInstance() 生成实例,Fragment 会 setArguments

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
private Object _navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
// ...
switch (postcard.getType()) {
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;
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 android.support.v4.app.Fragment) {
((android.support.v4.app.Fragment) instance).setArguments(postcard.getExtras());
}

return instance;
} catch (Exception ex) {
// ...
}
case METHOD:
case SERVICE:
default:
return null;
}
return null;
}
作者

Dench

发布于

2020-08-27

更新于

2020-08-27

许可协议

CC BY-NC-SA 4.0

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×