一、原理浅析

在同一个模块类的页面可以相互持有引用从而实现页面跳转的功能,在不同模块间的跳转则可以使用ARouter路由框架解决。

从A界面跳转到B界面的过程进行分析大致分为四个过程。

Android ARouter 生成Fragment android arouter原理_初始化

1、注册

B界面将类的信息以k-v的形式向ARouter注册。

2、查询

A界面发起跳转请求,通过key查询到ARouter中注册的类信息,并将跳转信息(跳转传递的参数、跳转动画信息等)传递至ARouter。

3、结合

ARouter查询到目标界面的信息后,将A界面的类信息与B界面的类信息进行结合。

4、跳转

将结合后的信息实现跳转。

A界面跳转到B界面ARouter做的工作

Android ARouter 生成Fragment android arouter原理_初始化_02

1.通过apt技术利用注解编译时生成类,封装目标界面类的类信息。
2.在初始化时,把编译生成的类通过key-value的方式存储在ARouter中。
3.发送操作者通过key获取到目标界面类的信息。
4.把发送操作者的信息与目标界面类信息进行结合或者关联在一起。
5.实现跳转功能。

二、基本使用

1、添加依赖配置

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'

2、添加注解

// 在支持路由的页面上添加注解(必选)
// 这里的路径需要注意的是至少需要有两级,/xx/xx
@Route(path = "/test/activity")
public class YourActivity extend Activity {
    ...
}

3、初始化(推荐在Application中进行)

if (isDebug()) {           // 这两行必须写在init之前,否则这些配置在init过程中将无效
    ARouter.openLog();     // 打印日志
    ARouter.openDebug();   // 开启调试模式
}
ARouter.init(mApplication); // 尽可能早,推荐在Application中初始化

4、实现跳转

// 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)

拦截器的使用很好的体现了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();

                    }
                });

            }
        });

四、Demo效果

Android ARouter 生成Fragment android arouter原理_拦截器_03


Android ARouter 生成Fragment android arouter原理_ide_04

Android ARouter 生成Fragment android arouter原理_ide_05


Android ARouter 生成Fragment android arouter原理_初始化_06