Skip to content

拦截器

xiaojinzi123 edited this page Jun 25, 2019 · 5 revisions

局部路由拦截器

框架中的路由拦截器是指某一个类实现了 RouterInterceptor 接口,那么这个拦截器就可以被使用了,

假设我写了一个拦截器如下

public class XxxInterceptor implements RouterInterceptor {
    @Override
    public void intercept(Chain chain) throws Exception {
        chain.proceed(chain.request());
    }
}

比如在一次跳转代码中使用

Router.with(this)
  	.host(xxx)
  	.path(xxx)
  	// 这里就在本次路由中使用了 XxxInterceptor 拦截器
  	// 并且方法是一个可变数组,你可以任意使用多个,拦截器的执行顺序按照参数传入的先后顺序
  	.interceptor(XxxInterceptor.class,......)
  	.navigate()

比如在一个目标界面使用,这种把拦截器在目标界面使用称之为页面拦截器

@RouterAnno(
		host = "app",
  	path = "main",
  	// 表示所有跳转到本界面的路由都会经过这里声明的拦截器
  	interceptor = [XxxInterceptor.class,......]
)
public XxxActivity extends Activity {
  	// ......
}

全局路由拦截器

如何使用:全局拦截器需要使用 @GlobalInterceptorAnno(priority = 4) 注解标记,这个拦截器会在业务组件被加载的时候自动加载到框架中,会拦截到每一个路由请求.参数 priority 是指这个拦截器的优先级,数值越大,优先级越大

使用场景: 比如您需要对所有的路由做处理、做分析等等

@GlobalInterceptorAnno(priority = 4)
public class Component1Interceptor2 implements RouterInterceptor {

    public Component1Interceptor2(Application application) {
    }

    @Override
    public void intercept(Chain chain) throws Exception {
        chain.proceed(chain.request());
    }

}

给你的拦截器起一个别名

使用 @InterceptorAnno(value="xxx") 标记你的拦截器,你的拦截器就有了一个别名叫做 xxx,这个有什么用呢?

上面的直接使用 xxx.class 是直接引用到 Class 了,但是在组件化中你要使用的拦截器可能根本不能引用到,这时候别名就起作用了,你可以把拦截器声明到任何一个模块,然后任何一个地方使用这个别名就可以使用到

使用场景1:A 模块需要使用User模块的登录拦截器,使用这个拦截器就可以实现自动登录

在User模块声明登录拦截器

// 这里一般使用一个常量,我这里是为了看的更清晰
@InterceptorAnno("user.login")
public class UserLoginInterceptor implements RouterInterceptor {

    public UserLoginInterceptor(Context app) {
    }

    @Override
    public void intercept(final Chain chain) throws Exception {
            // ......完成整个登陆验证过程,代码有点长,建议看源码中的 LoginInterceptor
    }
}

在 B 模块的界面上使用

@RouterAnno(
        host = "component1",
        value = "testLogin",
  			// 使用了这个拦截器,所有跳转到此界面的都会自动完成登录过程
        interceptorNames = "user.login"
)
public class Component1TestLoginAct extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.component1_test_login_act);
        getSupportActionBar().setTitle("测试登录");
    }

}

这样子我们就跨组件的使用了别的模块提供的拦截器

使用场景2: A 界面是一个订单确认界面,好多入口都可以跳转到这里下订单,但是这个界面需要做一个事情,就是跳转过来之前你需要做一下参数的检查,那么这段代码你放在前面的界面实现肯定不靠谱,因为这样子每一个界面都要做这件事情,而且以后新加一个入口你都要注意这个事情.假如你放到目标界面做,那么已经跳转过来了,用户已经看到确认订单的界面了,然后检测不通过的话界面又销毁掉,明显这样子给用户的体验又不好了,所以这种就这个界面会使用的拦截器,你可以这样子来做

声明订单检测的拦截器,不需要使用注解标记

public class CheckBeforOrderInterceptor implements RouterInterceptor {

        @Override
        public void intercept(RouterInterceptor.Chain chain) throws Exception {
                // 去做检测的事情
        }
}

使用这个拦截器,参数为 Class 类型

@RouterAnno(
        host = ModuleConfig.Main.NAME,
        value = ModuleConfig.Main.MAIN_ORDER_CONFIRM,
        interceptors = {CheckBeforOrderInterceptor.class}
)
public class OrderConfirmAct extends Activity {
}

当然这里的拦截器你完全可以使用 @InterceptorAnno 注解然后起一个名字,但是这种不对外的拦截器,这样子使用更加的简单

You can’t perform that action at this time.