ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Arouter讲解4_Core,android应用开发基础答案

2022-01-14 14:01:38  阅读:122  来源: 互联网

标签:Core return postcard callback Arouter new path android null


LogisticsCenter.completion(postcard);
return (T) postcard.getProvider();
} catch (NoRouteFoundException ex) {
logger.warning(Consts.TAG, ex.getMessage());
return null;
}
}

从Warehouse.providersIndex 的HashMap中根据全限定名得到 RouteMeta

public static Postcard buildProvider(String serviceName) {
RouteMeta meta = Warehouse.providersIndex.get(serviceName);

if (null == meta) {
return null;
} else {
return new Postcard(meta.getPath(), meta.getGroup());
}
}

刚刚new 出来的 Postcard 只含有 path 和Group,还需要对其他信息进行补充。先从 routes 缓存中根据path获取 RouteMeta,如果缓存中没有,可以动态添加。

如果缓存中有了,就把数据填充到 Postcard

public synchronized static void completion(Postcard postcard) {
if (null == postcard) {
throw new NoRouteFoundException(TAG + “No postcard!”);
}

// 先从缓存类找
RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath());

if (null == routeMeta) {
// Maybe its does’t exist, or didn’t load.
// 缓存里没有
// 可以动态添加,但是先要把group添加进来
if (!Warehouse.groupsIndex.containsKey(postcard.getGroup())) {
throw new NoRouteFoundException(TAG + “There is no route match the path [” + postcard.getPath() + “], in group [” + postcard.getGroup() + “]”);
} else {
// Load route and cache it into memory, then delete from metas.
try {
if (ARouter.debuggable()) {
logger.debug(TAG, String.format(Locale.getDefault(), “The group [%s] starts loading, trigger by [%s]”, postcard.getGroup(), postcard.getPath()));
}

// 动态添加
addRouteGroupDynamic(postcard.getGroup(), null);

if (ARouter.debuggable()) {
logger.debug(TAG, String.format(Locale.getDefault(), “The group [%s] has already been loaded, trigger by [%s]”, postcard.getGroup(), postcard.getPath()));
}
} catch (Exception e) {
throw new HandlerException(TAG + “Fatal exception when loading group meta. [” + e.getMessage() + “]”);
}

completion(postcard); // Reload
}
} else {
// 从缓存取数据
postcard.setDestination(routeMeta.getDestination()); // 路
由目标类
postcard.setType(routeMeta.getType()); // 路由的类型 RouteType ,可以是 ACTIVITY、SERVICE、PROVIDER 、CONTENT_PROVIDER、FRAGMENT等
postcard.setPriority(routeMeta.getPriority()); // 权限值
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: // if the route is provider, should find its instance
// Its provider, so it must implement 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) {
logger.error(TAG, “Init provider failed!”, e);
throw new HandlerException(“Init provider failed!”);
}
}
postcard.setProvider(instance); // 拿到了实例对象
postcard.greenChannel(); // 绿色通道, Provider不受拦截器的影响
break;
case FRAGMENT:
postcard.greenChannel(); // Fragment 类型也走绿色通道,不受拦截器的影响
default:
break;
}
}
}

build

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

我们用build进行源码分析,首先

protected Postcard build(String path) {
if (TextUtils.isEmpty(path)) {
throw new HandlerException(Consts.TAG + “Parameter is invalid!”);
} else {
PathReplaceService pService = ARouter.getInstance().navigation(PathReplaceService.class);
if (null != pService) {
path = pService.forString(path);
}
// 如果有PathReplaceService ,这里的path已经经过PathReplaceService, afterReplace就是为true,后面就不要到 PathReplaceService了
return build(path, extractGroup(path), true);
}
}

如果实现 PathReplaceService ,可以对path进行拦截与修改。

public interface PathReplaceService extends IProvider {

/**

  • For normal path.
  • @param path raw path
    */
    String forString(String path);

/**

  • For uri type.
  • @param uri raw uri
    */
    Uri forUri(Uri uri);
    }

protected Postcard build(String path, String group, Boolean afterReplace) {
if (TextUtils.isEmpty(path) || TextUtils.isEmpty(group)) {
throw new HandlerException(Consts.TAG + “Parameter is invalid!”);
} else {
if (!afterReplace) {
PathReplaceService pService = ARouter.getInstance().navigation(PathReplaceService.class);
if (null != pService) {
path = pService.forString(path);
}
}
return new Postcard(path, group);
}
}

protected Object navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {

// 在 navigation之前 我们还有一次机会修改Postcard,是否需要被路由
PretreatmentService pretreatmentService = ARouter.getInstance().navigation(PretreatmentService.class);
if (null != pretreatmentService && !pretreatmentService.onPretreatment(context, postcard)) {
// 条件不满足,不再 navigation
// Pretreatment failed, navigation canceled.
return null;
}

// Set context to postcard.
postcard.setContext(null == context ? mContext : context);

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
}

// Arouter init后,会获取 InterceptorService
if (!postcard.isGreenChannel()) { // It must be run in async thread, maybe interceptor cost too mush time made ANR.
//fragment、provide都是绿色通道
interceptorService.doInterceptions(postcard, new InterceptorCallback() {
/**

  • Continue process
  • @param postcard route meta
    */
    @Override
    public void onContinue(Postcard postcard) {
    _navigation(postcard, requestCode, callback);
    }

/**

  • Interrupt process, pipeline will be destory when this method called.
  • @param exception Reson of interrupt.
    */
    @Override
    public void onInterrupt(Throwable exception) {
    if (null != callback) {
    callback.onInterrupt(postcard);
    }

logger.info(Consts.TAG, "Navigation failed, termination by interceptor : " + exception.getMessage());
}
});
} else {
return _navigation(postcard, requestCode, callback);
}

return null;
}

private Object _navigation(final Postcard postcard, final int requestCode, final NavigationCallback callback) {
final Context currentContext = postcard.getContext();

switch (postcard.getType()) {
case ACTIVITY:
// 和我们平时用Intetn打开Activity一样
// Build intent
final Intent intent = new Intent(currentContext, postcard.getDestination());
intent.putExtras(postcard.getExtras()); // 额外的参数

// Set flags.
int flags = postcard.getFlags();
if (0 != flags) {
intent.setFlags(flags);
}

// Non activity, need FLAG_ACTIVITY_NEW_TASK
if (!(currentContext instanceof Activity)) {
intent.addFlags(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();// 如果是provide,之间返回
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) {
logger.error(Consts.TAG, "Fetch fragment instance error, " + TextUtils.formatStackTrace(ex.getStackTrace()));
}
case METHOD:
case SERVICE:
default:
return null;
}

return null;
}

InterceptorService

@Route(path = “/arouter/service/interceptor”)
public class InterceptorServiceImpl implements InterceptorService

先到子线程中初始化,按照顺序执行我们定义的拦截器,因为拦截方法中可能有耗时操作,引起ANR,所以放在子线程中执行拦截操作。

@Override
public void init(final Context context) {
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();
}
}
}
});
}

@Override
public void doInterceptions(final Postcard postcard, final InterceptorCallback callback) {
if (MapUtils.isNotEmpty(Warehouse.interceptorsIndex)) {

checkInterceptorsInitStatus();

if (!interceptorHasInit) {
callback.onInterrupt(new HandlerException(“Interceptors initialization takes too much time.”));
return;
}

LogisticsCenter.executor.execute(new Runnable() {
@Override
public void run() {
//
CancelableCountDownLatch interceptorCounter = new CancelableCountDownLatch(Warehouse.interceptors.size());
try {
_execute(0, interceptorCounter, postcard);
interceptorCounter.await(postcard.getTimeout(), TimeUnit.SECONDS);
if (interceptorCounter.getCount() > 0) { // Cancel the navigation this time, if it hasn’t return anythings.
callback.onInterrupt(new HandlerException(“The interceptor processing timed out.”));
} else if (null != postcard.getTag()) { // Maybe some exception in the tag.
callback.onInterrupt((Throwable) postcard.getTag());
} else {
callback.onContinue(postcard);
}
} catch (Exception e) {
callback.onInterrupt(e);
}
}
});
} else {
callback.onContinue(postcard);
}
}

private static void _execute(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();
// 处理完成,交给下一个拦截器
_execute(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) {
// Last interceptor execute over with fatal exception.

postcard.setTag(null == exception ? new HandlerException(“No message.”) : exception); // save the exception message for backup.
counter.cancel();
// Be attention, maybe the thread in callback has been changed,
// then the catch block(L207) will be invalid.
// The worst is the thread changed to main thread, then the app will be crash, if you throw this exception!
// if (!Looper.getMainLooper().equals(Looper.myLooper())) { // You shouldn’t throw the exception if the thread is main thread.
// throw new HandlerException(exception.getMessage());
// }
}
});
}
}

inject

依赖注入,经过 Autowired 注解的 类,会自动生成类似下面这样的类,先获取Test3Activity这个类名,利用这个类名追加 ` ARouter$$Autowired,会得到

Test3Activity ARouter$$Autowired 这个类,实例化这个对象,调用这个对象中的inject方法,参数就是 Test3Activity 对象。

image-20210513234722439.png

image-20210513234800196.png

ad is main thread.
// throw new HandlerException(exception.getMessage());
// }
}
});
}
}

inject

依赖注入,经过 Autowired 注解的 类,会自动生成类似下面这样的类,先获取Test3Activity这个类名,利用这个类名追加 ` ARouter$$Autowired,会得到

Test3Activity ARouter$$Autowired 这个类,实例化这个对象,调用这个对象中的inject方法,参数就是 Test3Activity 对象。

[外链图片转存中…(img-fOd7etwb-1642139381478)]

[外链图片转存中…(img-neZplBRe-1642139381478)]

标签:Core,return,postcard,callback,Arouter,new,path,android,null
来源: https://blog.csdn.net/m0_66145114/article/details/122492811

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有