ARouter路由简单使用以及源码解析

ARouter相关文章虽然对,作为学习笔记使用,有问题希望能够尽情提出,共同交流
蒋八九

基本使用:

Application中的注册:

@Override
public void onCreate() {
    super.onCreate();
    //官方建议推荐在Application中初始化
    ARouter.init(this);
}
@Override
public void onTerminate() {
    super.onTerminate();
    ARouter.getInstance().destroy();
}

Activity中:

类必须注册路由地址
@Route(path = Constance.PATH_MAINACTIVITY)
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
注册路由
        ARouter.getInstance().inject(this);
补充fragment的获取
Fragment thirdFragment = (Fragment) ARouter.getInstance().build(PATH_THIEDFRAGMENT).navigation();
getSupportFragmentManager().beginTransaction().replace(R.id.fird, thirdFragment).commitNow();

        findViewById(R.id.mian_tv).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
跳转路由
                ARouter.getInstance().build(Constance.PATH_SECONDACTIVITY)
                        .withInt("id", 1)
                        .withString("key", "12345")
                        .withParcelable("person", new Person("蒋八九", 18))
                        .navigation(MainActivity.this, 123, new NavigationCallback() {
                            @Override
                            public void onFound(Postcard postcard) {
                                Log.e(TAG, "onFound:找到路由地址");
                            }
                            @Override
                            public void onLost(Postcard postcard) {
                                Log.e(TAG, "onLost:没找到路由地址");
                            }
                            @Override
                            public void onArrival(Postcard postcard) {
                                Log.e(TAG, "onArrival,跳转成功");
                            }
                            @Override
                            public void onInterrupt(Postcard postcard) {
                                Log.e(TAG, "onInterrupt:路由拦截");
                            }
                        });
            }
        });
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.e(TAG, "onActivityResult:requestCode" + requestCode + ";;;resultCode" + resultCode);
    }
}

Interceptor的使用

这里数字越小,优先级越大,类继承IInterceptor

@Interceptor(priority = -2) 
public class BusinessInterceptor implements IInterceptor {
    @Override
    public void process(Postcard postcard, InterceptorCallback callback) {
        if (postcard.getPath().equals(Constance.PATH_SECONDACTIVITY)) {
            Log.e(TAG, "拦截 ,拦截后在navigationCallback中的onInterrupt中会回调,然后结束");
            callback.onInterrupt(new Throwable("-----"));
        }else{
            Log.e(TAG, "继续往下执行跳转");
            callback.onContinue(postcard);
        }
    }
    @Override
    public void init(Context context) {
        Log.e(TAG, "UserInterceptor-拦截器-init: ");
    }
}

APT的理解和简单使用:

APT——Android annotation processing tool,注解处理器,它用于在编译期扫描和处理注解,然后通过javapoet生成一个java文件,然后存放到指定的文件中。优点就是方便简单,少写很多代码。

步骤一:建一个apt-annotation,定义一个注解。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface Route {
    String path();
}

步骤二:建一个apt-processor,解析处理注解。

1、将注解和javaPoet作为依赖添加进来
2、继承AbstractProcessor,重写init()、getSupportAnnotationTypes(),getSupportSourceVersion()、process()

添加依赖:
implementation 'com.alibaba:arouter-annotation:1.0'     自定义的注解
implementation 'com.squareup:javapoet:1.8.0'            这个是用来自动生成java文件的
AutoService固定写法,用来注册。
@AutoService(Processor.class)
支持的注解处理器类型,让注解处理器处理。
@SupportedAnnotationTypes(ANNOTATION_TYPE_INTECEPTOR)
public class InterceptorProcessor extends BaseProcessor {
    private Map<Integer, Element> interceptors = new TreeMap<>();
    private TypeMirror iInterceptor = null;
    //文件生成器 类/资源,Filter用于创建新的源文件,class文件预计辅助文件
    private Filer mFiler ;
    //操作Elememts工具类(类、函数、属性都是Element)
private Elements elementUtils ;
    //type(类信息)工具类,包含用于操作TypeMirror的工具方法
private Types typeUtils ;
在这里初始化一些工具类。主要用于一些初始化的操作,通过该方法的参数processingEnvironment可以获取一些有用的工具类
    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
	mFiler = processingEnv.getFiler();
	types = processingEnv.getTypeUtils();
	elementUtils = processingEnv.getElementUtils();
	typeUtils = new TypeUtils(types, elementUtils);
        iInterceptor = elementUtils.getTypeElement(Consts.IINTERCEPTOR).asType();
    }
1、根据roundEvironment的getElementsAnnotationWith(注解.class)方法获取所有被该注解注释的元素。然后遍历所有elements元素,通过getAnnotation去获得所有注解接口,然后调用接口中的方法即可获得参数。
2、封装MethodSpec、封装TypeSpec,然后通过javaFile生成java文件并写入到file中。
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
        if (CollectionUtils.isNotEmpty(annotations)) {
        Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(Interceptor.class);
        parseInterceptors(elements);
            return true;
        }
        return false;
    }
    private void parseInterceptors(Set<? extends Element> elements) throws IOException {
            for (Element element : elements) {
                 Interceptor interceptor = element.getAnnotation(Interceptor.class);
                 Element lastInterceptor = interceptors.get(interceptor.priority());
                 }
                 interceptors.put(interceptor.priority(), element);
            }
            TypeElement type_ITollgate = elementUtils.getTypeElement(IINTERCEPTOR);
            TypeElement type_ITollgateGroup = elementUtils.getTypeElement(IINTERCEPTOR_GROUP);
            ParameterizedTypeName inputMapTypeOfTollgate = ParameterizedTypeName.get(
                    ClassName.get(Map.class),
                    ClassName.get(Integer.class),
                    ParameterizedTypeName.get(
                            ClassName.get(Class.class),
                            WildcardTypeName.subtypeOf(ClassName.get(type_ITollgate))
                    )
            );
            ParameterSpec tollgateParamSpec = ParameterSpec.builder(inputMapTypeOfTollgate, "interceptors").build();
封装方法
            MethodSpec.Builder loadIntoMethodOfTollgateBuilder = MethodSpec.methodBuilder(METHOD_LOAD_INTO)
                    .addAnnotation(Override.class)
                    .addModifiers(PUBLIC)
                    .addParameter(tollgateParamSpec);
            if (null != interceptors && interceptors.size() > 0) {
                for (Map.Entry<Integer, Element> entry : interceptors.entrySet()) {
                    loadIntoMethodOfTollgateBuilder.addStatement("interceptors.put(" + entry.getKey() + ", $T.class)", ClassName.get((TypeElement) entry.getValue()));
                }
           }
封装类TypeSpec,然后通过javaFile整合类和方法生成java文件并写入file文件中。
            JavaFile.builder(PACKAGE_OF_GENERATE_FILE,
                    TypeSpec.classBuilder(NAME_OF_INTERCEPTOR + SEPARATOR + moduleName)
                            .addModifiers(PUBLIC)
                            .addJavadoc(WARNING_TIPS)
                            .addMethod(loadIntoMethodOfTollgateBuilder.build())
                            .addSuperinterface(ClassName.get(type_ITollgateGroup))
                            .build()
            ).build().writeTo(mFiler);
    }
}

源码分析:

类的介绍:

ARouter:是个外观,里面的方法都是调用_ARouter来实现的,
_ARouter:外观模式模式,通过这个类统一调用Logger、LogisticsCenter的功能,为了实现外观模式,build和navigation的方法也通过ARouter中转一下。这个设计比较神奇。其中natigation方法是核心方法,postcard填充,callback回调,拦截器调用,降级策略、界面跳转都在这里实现。
LogisticsCenter:物流中心,主要方法是init(获取base.apk中以com.alibaba.android.arouter.routers开头的全类名,存入hashset缓存中)和complete(填充postcard)。

ARouter的初始化:

初始化主要目的是:获取关于router全类名的hashmap,然后填充warehouse中的map。
主要步骤是:

  1. _ARouter.init() ——> LogisticsCenter.init();
  2. 遍历base.apk中的全类名,获取以com.alibaba.android.arouter.routes开头的所有全类名,将他们存放hashset缓存,然后将hashset存入sp中。
  3. 根据hashset中的全类名,反射得到IRouterRoot、interceptor、privider实例,并通过loadInto方法将warehouse中的map赋值。

为什么只获取这三个并填充,因为有Routerroot就有分组,就能获取到其他需要跳转的具体类,其他的可能点击的时候才加载,所以不需要初始化的时候浪费那么多资源。
这使用前必须进行init操作,官方建议写在application中

ARouter.init(this);
public static void init(Application application) {
    if (!hasInit) {
        logger = _ARouter.logger;
        _ARouter.logger.info(Consts.TAG, "ARouter init start.");
初始化ARouter
        hasInit = _ARouter.init(application);
        if (hasInit) {
初始化interceptor拦截器
            _ARouter.afterInit();
        }
    }
}

_ARouter.java类ARouter core (Facade patten),是个外观模式,外观模式相当于util工具类,将杂七杂八的都封装起来,统一处理

final class _ARouter {
首先这里开了一个线程池,继承与ThreadPoolExecutor的核心线程和最大线程数相同都是cup核数+1,阻塞队列是ArrayBlockingQueue
    private volatile static ThreadPoolExecutor executor = DefaultPoolExecutor.getInstance();
    protected static synchronized boolean init(Application application) {
        mContext = application;
Init方法最终是调用了Logistics Center的init方法来实现ARouter的初始化操作。
        LogisticsCenter.init(mContext, executor);
        hasInit = true;
        return true;
    }
}

LogisticsCenter(LogisticsCenter contain all of the map.)包含了所有的map,在这个init中完成ARouter的初始化工作,这里的主要目的:

1、遍历base.java中的左右全类名,取出以com.alibaba.android.arouter.routes开头的全类名放入hashset集合中并存放到sp的CASH中。
2、遍历hashset中的全类名,通过反射构造函数的方法分别得到IRouterRoot、IIterceptorGroup、IProviderGroup的实例,并通过loadInto方法,给WareHouse中的对应的map赋值。
public synchronized static void init(Context context, ThreadPoolExecutor tpe) throws HandlerException {
    mContext = context;
    executor = tpe;
    try {
	Set<String> routerMap;
如果是debug模式或者是第一次使用ARouter进入;
	if (ARouter.debuggable() || PackageUtils.isNewVersion(context)) {
通过遍历base.apk中所有全类名,将以com.alibaba.android.arouter.routes开头的包名通通找出来,并封装成HashSet,当debug或者是第一次进入的时候,缓存进去,以后就直接获取使用。
		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 {
不是第一次进来直接从cash缓存中获取hashMap的值
		routerMap = new HashSet<>(context.getSharedPreferences(AROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).getStringSet(AROUTER_SP_KEY_MAP, new HashSet<String>()));
	}
获取到hashmap之后遍历,通过构造函数反射分别获取IRouteRoot、IInterceptorGroup、IProviderGroup的实例对象,然后调用对象中的loadInto方法,对WareHouse中的map进行赋值。
	for (String className : routerMap) {
	 if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_ROOT)) {
	    ((IRouteRoot) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.groupsIndex);
	  } else if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_INTERCEPTORS)) {
	    ((IInterceptorGroup) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.interceptorsIndex);
	  } else if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_PROVIDERS)) {
	    ((IProviderGroup) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.providersIndex);
	  }
	}
    } catch (Exception e) {
    }
}

ARouter的注册

注册的主要目的是为了得到AutowiredServiceImpl实例,然后调用它的autowire方法完成传递值的自动装箱功能。
注册的主要步骤:

  1. 通过/arouter/service/autowire路由获取到AutowiredServiceImpl全类路径,通过反射得到AutowireServiceImpl实例,然后调用其中的autowired方法。
  2. 在autowired方法中,先获取当前类xxx$ARouter$$Autowired全类名,通过构造反射获取实例,然后调用其中的inject方法对传值参数进行自动装箱处理。
ARouter.getInstance().inject(this);          
public void inject(Object thiz) {
    _ARouter.inject(thiz);                   
}
biuld的作用是得到一个包含path和group的Postcard的构造。最后通过navigation方法执行。
static void inject(Object thiz) {
    AutowiredService autowiredService = ((AutowiredService) ARouter.getInstance().build("/arouter/service/autowired").navigation());
    if (null != autowiredService) {
        autowiredService.autowire(thiz);
    }
}

最后在navigation在_ARouter中执行,首先填充postcard。如果填充异常,则调用NavigationCallback的onLost方法,如果没有写这个回调方法,那么就通过全局降级。这里注册过程不涉及到这一步。
3. 在navigation中调用LogisticsCenter.complete()方法填充postCard,postcard是RouterMeta的子类,注册过程中主要做两件事。第一、填充destination、type、extra等基本参数;第二、根据注册的provider分支填充postcast的provider值得到AutowiredServiceImpl实例,同时开通绿色通道。
4. 最后调用_navigation()方法真正执行,注册过程中type类型直接走Provider分支,主要是为了得到post.getProvider()对象,也就是AutowiredServiceImpl对象。

扫描二维码关注公众号,回复: 11580799 查看本文章
protected Object navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
    try {
        LogisticsCenter.completion(postcard);
    } catch (NoRouteFoundException ex) {
        if (null != callback) {
            callback.onLost(postcard);
        } else {
         DegradeService degradeService = ARouter.getInstance().navigation(DegradeService.class);
            if (null != degradeService) {
                degradeService.onLost(context, postcard);
            }
        }
        return null;
    }
    if (null != callback) {
        callback.onFound(postcard);
    }
    .............
return _navigation(context, postcard, requestCode, callback);
}

public synchronized static void completion(Postcard postcard) {
    RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath());
    if (null == routeMeta) {
        Class<? extends IRouteGroup> groupMeta = Warehouse.groupsIndex.get(postcard.getGroup());
        if (null == groupMeta) {
	...........
        } else {
            try {
                IRouteGroup iGroupInstance = groupMeta.getConstructor().newInstance();
                iGroupInstance.loadInto(Warehouse.routes);
                Warehouse.groupsIndex.remove(postcard.getGroup());
            } catch (Exception e) {
		...........
            }
            completion(postcard);
        }
    } else {
        postcard.setDestination(routeMeta.getDestination());  //填充XXX.class
        postcard.setType(routeMeta.getType());                //填充类型,Activity还是Fragment
        postcard.setPriority(routeMeta.getPriority());        //填充优先级,最小堆
        postcard.setExtra(routeMeta.getExtra());              //填充传参
        ...........
        switch (routeMeta.getType()) {
            case PROVIDER:
                Class<? extends IProvider> providerMeta = (Class<? extends IProvider>) routeMeta.getDestination();
                IProvider instance = Warehouse.providers.get(providerMeta);
                if (null == instance) {
                    IProvider provider;
                    try {
                        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());
                    }
                }
                postcard.setProvider(instance);
                postcard.greenChannel();
                break;
            case FRAGMENT:
                postcard.greenChannel();
            default:
                break;
        }
    }
}
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()) {
        case ACTIVITY:
            ...............
            break;
        case PROVIDER:
            return postcard.getProvider();注册过程中主要是为了得到AutowiredServiceimpl对象。
        case BOARDCAST:
        case CONTENT_PROVIDER:
        case FRAGMENT:
            ...............
        case METHOD:
        case SERVICE:
        default:
            return null;
    }
    return null;
}

最后自动装箱功能通过autowire方法来实现。

public void autowire(Object instance) {
    String className = instance.getClass().getName();
    try {
        if (!blackList.contains(className)) {
            ISyringe autowiredHelper = classCache.get(className);
            if (null == autowiredHelper) {
通过反射获取$$ARouter$$Autowired的对象,并强转为ISyring成功,表示该类中添加了Autowire的注解。
                autowiredHelper = (ISyringe) Class.forName(instance.getClass().getName() + SUFFIX_AUTOWIRED).getConstructor().newInstance();
            }
获取成功,就调用inject方法实现传参的自动装箱功能。并将对象保存到缓存中。
            autowiredHelper.inject(instance);
            classCache.put(className, autowiredHelper);
        }
    } catch (Exception ex) {
如果没有@autowire注释,就将该类添加到黑名单,下次就不装箱了。依据是强转ISyring对象失败。
        blackList.add(className);
    }
}

ARouter的跳转

跳转过程和注册过程相似,这里多了NavigationCallback和requestCode,而且type是Activity或者fragment。

  1. 通过build得到带有path和group的一个postcard对象。
  2. 通过complete方法填充postcard(如果postcard=null或者找不到分组路由全类名,回调onLost,如果没有回调,则执行降级)
  3. 设置判断是否拦截(Fragment默认不拦截),并进行拦截操作。
  4. 调用_navigation方法的Activity或者Fragment分支,最终完成跳转。
ARouter.getInstance().build(Constance.PATH_SECONDACTIVITY)
        .withInt("id", 1)
        .withString("key", "12345")
        .withParcelable("person", new Person("蒋八九", 18))
        .navigation(MainActivity.this, 123, new NavigationCallback() {
            @Override
            public void onFound(Postcard postcard) {
postcard填充完毕,没有异常
            }
            @Override
            public void onLost(Postcard postcard) {
如果postcard==null或者通过路由分组找不到路由组全类名
            }
            @Override
            public void onArrival(Postcard postcard) {
最终startActivity结束,调用onArrival
            }
            @Override
            public void onInterrupt(Postcard postcard) {
在自定义拦截器中调用interrupt方法
            }
        });
        
protected Object navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
    try {
这里填充postcard,fragment默认不拦截。
        LogisticsCenter.completion(postcard);
    } catch (NoRouteFoundException ex) {
        if (null != callback) {
如果postcard==null或者在分组中找不到目标路由的全类名。在回调onLost方法通知
            callback.onLost(postcard);
        } else {
没有写回调,则进行降级
          DegradeService degradeService=ARouter.getInstance().navigation(DegradeService.class);
            if (null != degradeService) {
                degradeService.onLost(context, postcard);
            }
        }
        return null;
    }
    if (null != callback) {
填充postcard完成后,通知onFound
        callback.onFound(postcard);
    }
    if (!postcard.isGreenChannel()) {
如果自定义了interceptor类,则执行拦截操作,PROVIDER和Fragment默认不进行拦截。
        interceptorService.doInterceptions(postcard, new InterceptorCallback() {
            @Override
            public void onContinue(Postcard postcard) {
拦截完后调用onContinue方法继续执行
                _navigation(context, postcard, requestCode, callback);
            }
            @Override
            public void onInterrupt(Throwable exception) {
拦截完后调用onInterrupt方法通知用户
                if (null != callback) {
                    callback.onInterrupt(postcard);
                }}
        });
    } else {
        return _navigation(context, postcard, requestCode, callback);
    }
    return null;
}

自定义拦截器:

  1. 加@interceptor注解
  2. 添加优先级,这是个treemap
  3. 实现IInterceptor
  4. 在callback中必须调用onContinue方法才能继续往下执行
  5. 在callback中执行onInterrupt方法抛出异常终止跳转。最终执行navigationCallback的onInterrupt
@Interceptor(priority = -2)
public class BusinessInterceptor implements IInterceptor {
    @Override
    public void process(Postcard postcard, InterceptorCallback callback) {
        if (postcard.getPath().equals(Constance.PATH_SECONDACTIVITY)) {
            callback.onInterrupt(new Throwable("拦截"));
        }else{
            Log.e(TAG, "继续执行跳转 ");
            callback.onContinue(postcard);
        }
    }
    @Override
    public void init(Context context) {
        Log.e(TAG, "UserInterceptor-拦截器-init: ");
    }
}

不拦截或者拦截调用onContinue方法,才能完成最终的跳转_navigation方法。
对于Activity类:

  1. 获取预跳转的Activity类,添加与传递的值。
  2. 如果当前上下文不是Activity,如通知栏或者广播跳转,需要new_task栈。
  3. 最后通过handler执行startActivity()和overridePendingTransition()执行跳转功能和动画功能。
  4. 完成后调用onArrival
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()) {
        case ACTIVITY:
            final Intent intent = new Intent(currentContext, postcard.getDestination());
            intent.putExtras(postcard.getExtras());
            int flags = postcard.getFlags();
            if (-1 != flags) {
                intent.setFlags(flags);
            } else if (!(currentContext instanceof Activity)) {
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            }
            new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    if (requestCode > 0) {
                        ActivityCompat.startActivityForResult((Activity) currentContext, intent, requestCode, postcard.getOptionsBundle());
                    } else {
                        ActivityCompat.startActivity(currentContext, intent, postcard.getOptionsBundle());
                    }
                    if ((0 != postcard.getEnterAnim() || 0 != postcard.getExitAnim()) && currentContext instanceof Activity) {
                        ((Activity) currentContext).overridePendingTransition(postcard.getEnterAnim(), postcard.getExitAnim());
                    }
                    if (null != callback) {
                        callback.onArrival(postcard);
                    }
                }
            });
            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) {
                logger.error(Consts.TAG, "Fetch fragment instance error, " + TextUtils.formatStackTrace(ex.getStackTrace()));
            }
        case METHOD:
        case SERVICE:
        default:
            return null;
    }
    return null;
}

降级策略

降级条件:

  1. 当postcast == null的时候,或者在map中根据group分组找不到对应的类时,将抛出NoRouteFoundException异常。
  2. 如果自定义NavigationCallback,将调用onLost()单体降级,否则将调用DegradeService的onLost作为全局降级。
官方例子写法:继承DegradeService即可
@Route(path = Constance.PATH_MYDEGRADE_SERVICE)
public class MyDegradeService implements DegradeService {
    @Override
    public void onLost(Context context, Postcard postcard) {
        Log.e("----", "onLost:全局降级策略 " );
    }
    @Override
    public void init(Context context) {
    }
}

依赖注入

依赖的注入就是自动装箱:autowired过程。
首先在arouter-api这个包中有个类叫做:AutowiredServiceImpl实现了Iprovider。并且添加了注释

@Route路径是arouter/service/autowired
@Route(path = "/arouter/service/autowired")
public class AutowiredServiceImpl implements AutowiredService {
...............
    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.
                    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.
        }
    }
}
因此这个类在编译的时候自动生成的类会添加到arouter分组中
public class ARouter\$\$Root\$\$arouterapi implements IRouteRoot {
  @Override
  public void loadInto(Map<String, Class<? extends IRouteGroup>> routes) {
    routes.put("arouter", ARouter\$\$Group\$\$arouter.class);
  }
}
从这个分组中可以根据path获取AutowiredServiceImpl和InterceptorServiceImpl两个类。
public class ARouter\$\$Group\$\$arouter implements IRouteGroup {
  @Override
  public void loadInto(Map<String, RouteMeta> atlas) {
    atlas.put("/arouter/service/autowired", RouteMeta.build(RouteType.PROVIDER, AutowiredServiceImpl.class, "/arouter/service/autowired", "arouter", null, -1, -2147483648));
    atlas.put("/arouter/service/interceptor", RouteMeta.build(RouteType.PROVIDER, InterceptorServiceImpl.class, "/arouter/service/interceptor", "arouter", null, -1, -2147483648));
  }
}
当在自定义的onCreate中添加ARouter.getInstance().inject(this)完成注入。这里根据path路径获取到AutowiredServiceImpl对象,最后调用其中的autowired方法,将this传入,通过this.getIntent()获取参数并赋值完成注入工作。
static void inject(Object thiz) {
    AutowiredService autowiredService = ((AutowiredService) ARouter.getInstance().build("/arouter/service/autowired").navigation());
    if (null != autowiredService) {
        autowiredService.autowire(thiz);
    }
}

猜你喜欢

转载自blog.csdn.net/massonJ/article/details/107956747