在同一个模块类的页面可以相互持有引用从而实现页面跳转的功能,在不同模块间的跳转则可以使用ARouter路由框架解决。
1、注册
B界面将类的信息以k-v的形式向ARouter注册。
2、查询
A界面发起跳转请求,通过key查询到ARouter中注册的类信息,并将跳转信息(跳转传递的参数、跳转动画信息等)传递至ARouter。
3、结合
ARouter查询到目标界面的信息后,将A界面的类信息与B界面的类信息进行结合。
4、跳转
将结合后的信息实现跳转。
1.通过apt技术利用注解编译时生成类,封装目标界面类的类信息。
2.在初始化时,把编译生成的类通过key-value的方式存储在ARouter中。
3.发送操作者通过key获取到目标界面类的信息。
4.把发送操作者的信息与目标界面类信息进行结合或者关联在一起。
5.实现跳转功能。
android {
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
}
dependencies {
// 替换成最新版本, 需要注意的是api
// 要与compiler匹配使用,均使用最新版可以保证兼容
compile 'com.alibaba:arouter-api:x.x.x'
annotationProcessor 'com.alibaba:arouter-compiler:x.x.x'
...
}
// 旧版本gradle插件(< 2.2),可以使用apt插件,配置方法见文末'其他#4'
// Kotlin配置参考文末'其他#5'
// 在支持路由的页面上添加注解(必选)
// 这里的路径需要注意的是至少需要有两级,/xx/xx
@Route(path = "/test/activity")
public class YourActivity extend Activity {
...
}
if (isDebug()) { // 这两行必须写在init之前,否则这些配置在init过程中将无效
ARouter.openLog(); // 打印日志
ARouter.openDebug(); // 开启调试模式
}
ARouter.init(mApplication); // 尽可能早,推荐在Application中初始化
// 1. 应用内简单的跳转(通过URL跳转在'进阶用法'中)
ARouter.getInstance().build("/test/activity").navigation();
// 2. 跳转并携带参数
ARouter.getInstance().build("/test/1")
.withLong("key1", 666L)
.withString("key3", "888")
.withObject("key4", new Test("Jack", "Rose"))
.navigation();
拦截器的使用很好的体现了AOP的思想,在进行页面跳转时往往会进行一些重复的操作,如登录信息的验证,权限的验证等。拦截器可以将这些事件在页面的跳转过程中进行处理,不必在每个需要验证的地方重复操作。下面以登录验证为例:
1、首先声明拦截器,添加注解@Interceptor,并实现IInterceptor接口,priority表示拦截器的优先级,name为拦截器名。process方法用于拦截事件的处理,poostcard中含有跳转过程中传递的目标信息等,可用于做判断。InterceptorCallback可以控制是否需要拦截,以及拦截后的回调处理事件。
@Interceptor(priority = 1, name = "登录拦截器")
public class LoginInterceptorImpl implements IInterceptor {
private String TAG = LoginInterceptorImpl.class.getSimpleName();
@Override
public void process(Postcard postcard, InterceptorCallback callback) {
Log.e(TAG, "process: Path ==" + postcard.getPath());
String path = postcard.getPath();
boolean isLogin = false;
if (isLogin) {
callback.onContinue(postcard);
} else {
switch (path) {
default:
callback.onInterrupt(null);
break;
}
}
}
@Override
public void init(Context context) {
Log.e("TestInterceptor", "process: " + LoginInterceptorImpl.class.getSimpleName() + " has init");
}
}
2、点击按钮4跳转到主页时,在拦截器中对跳转进行拦截,在onInterrupt中处理拦截后先跳转到登陆界面,并将目标界面的信息传递给登陆界面,登录成功后再进行跳转。
btn4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ARouter.getInstance().build(Const.HOME_ACTIVITY_PATH)
.withString("msg","需要登录")
.navigation(MainActivity.this, new NavigationCallback() {
@Override
public void onFound(Postcard postcard) {//找到了目标界面
Log.e(TAG, "btn4 onFound: ");
}
@Override//找不到目标页面
public void onLost(Postcard postcard) {
Log.e(TAG, "btn4 onLost: ");
}
@Override//跳转成功
public void onArrival(Postcard postcard) {
Log.e(TAG, "btn4 onArrival: ");
}
@Override//跳转被拦截
public void onInterrupt(Postcard postcard) {
Log.e(TAG, "btn4 onInterrupt: 被拦截 目标页面信息传递给登录界面 登陆成功后进行跳转");
ARouter.getInstance().build(Const.LOGIN_ACTIVITY_PATH)
.withString("target",Const.HOME_ACTIVITY_PATH)
.navigation();
}
});
}
});