为了项目解耦,实现模块的独立化,出现了组件化,而组件化中用作模块间通信的重要使者就是ARouter,今天就一起来看看这个神奇的工具。
- ARouter的原理?
- ARouter怎么实现页面拦截?
- 组件化中使用ARouter需要注意什么,或者说怎么正确应用到组件化中呢?
ARouter的原理
首先,我们了解下ARouter
是干嘛的?ARouter
是阿里巴巴研发的一个用于解决组件间,模块间界面跳转问题的框架。所以简单的说,就是用来跳转界面的,不同于平时用到的显式或隐式跳转,只需要在对应的界面上添加注解
,就可以实现跳转,看个案例:
@Route(path = "/test/activity")
public class YourActivity extend Activity {
...
}
//跳转
ARouter.getInstance().build("/test/activity").navigation();
使用很方便,通过一个path
就可以进行跳转了,那么原理是什么呢?
其实仔细思考下,就可以联想到,既然关键跳转过程是通过path
跳转到具体的activity
,那么原理无非就是把path
和Activity
一一对应起来就行了。没错,其实就是通过注释,通过apt
技术,也就是注解处理工具,把path和activity关联起来了。主要有以下几个步骤:
- 代码里加入的
@Route
注解,会在编译时期通过apt生成一些存储path和activity.class映射关系的类文件 - app进程启动的时候会加载这些类文件,把保存这些映射关系的数据读到内存里(保存在map里)
- 进行路由跳转的时候,通过
build()
方法传入要到达页面的路由地址,ARouter会通过它自己存储的路由表找到路由地址对应的Activity.class - 然后
new Intent
方法,如果有调用ARouter
的withString()
方法,就会调用intent.putExtra(String name, String value)
方法添加参数 - 最后调用
navigation()
方法,它的内部会调用startActivity(intent)进行跳转
ARouter怎么实现页面拦截
先说一个拦截器的案例,用作页面跳转时候检验是否登录,然后判断跳转到登录页面还是目标页面:
代码语言:javascript复制 @Interceptor(name = "login", priority = 6)
public class LoginInterceptorImpl implements IInterceptor {
@Override
public void process(Postcard postcard, InterceptorCallback callback) {
String path = postcard.getPath();
boolean isLogin = SPUtils.getInstance().getBoolean(ConfigConstants.SP_IS_LOGIN, false);
if (isLogin) {
// 如果已经登录不拦截
callback.onContinue(postcard);
} else {
// 如果没有登录,进行拦截
callback.onInterrupt(postcard);
}
}
@Override
public void init(Context context) {
LogUtils.v("初始化成功");
}
}
//使用
ARouter.getInstance().build(ConfigConstants.SECOND_PATH)
.withString("msg", "123")
.navigation(this,new LoginNavigationCallbackImpl());
// 第二个参数是路由跳转的回调
// 拦截的回调
public class LoginNavigationCallbackImpl implements NavigationCallback{
@Override
public void onFound(Postcard postcard) {
}
@Override
public void onLost(Postcard postcard) {
}
@Override
public void onArrival(Postcard postcard) {
}
@Override
public void onInterrupt(Postcard postcard) {
//拦截并跳转到登录页
String path = postcard.getPath();
Bundle bundle = postcard.getExtras();
ARouter.getInstance().build(ConfigConstants.LOGIN_PATH)
.with(bundle)
.withString(ConfigConstants.PATH, path)
.navigation();
}
}
拦截器实现IInterceptor
接口,使用注解@Interceptor
,这个拦截器就会自动被注册了,同样是使用APT技术自动生成映射关系类。这里还有一个优先级参数priority
,数值越小,就会越先执行。
怎么应用到组件化中
首先,在公用组件的build.gradle中添加依赖:
代码语言:javascript复制dependencies {
api 'com.alibaba:arouter-api:1.4.0'
annotationProcessor 'com.alibaba:arouter-compiler:1.2.1'
}
其次,必须在每个业务组件,也就是用到了arouter
的组件中都声明annotationProcessorOptions
,否则会无法通过apt生成索引文件,也就无法正常跳转了:
//业务组件的build.gradle
android {
defaultConfig {
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
}
dependencies {
annotationProcessor 'com.alibaba:arouter-compiler:1.2.1'
implementation '公用组件'
}
这个arguments
是用来设置给编译处理器的一些参数,这里就把[AROUTER_MODULE_NAME: project.getName()]
键值对传了过去,方便Arouter使用apt的时候进行数据处理,也是Arouter库所规定的配置。
然后就可以正常使用了。
Android开发者们,快来关注公众号【码上积木】,每天三问面试题,并详细剖析,助你成为offer收割机。 积累也是一种力量。