ARouter三问—腾讯真题

2020-10-29 16:39:49 浏览数 (1)

为了项目解耦,实现模块的独立化,出现了组件化,而组件化中用作模块间通信的重要使者就是ARouter,今天就一起来看看这个神奇的工具。

  • ARouter的原理?
  • ARouter怎么实现页面拦截?
  • 组件化中使用ARouter需要注意什么,或者说怎么正确应用到组件化中呢?

ARouter的原理

首先,我们了解下ARouter是干嘛的?ARouter是阿里巴巴研发的一个用于解决组件间,模块间界面跳转问题的框架。所以简单的说,就是用来跳转界面的,不同于平时用到的显式或隐式跳转,只需要在对应的界面上添加注解,就可以实现跳转,看个案例:

代码语言:javascript复制
@Route(path = "/test/activity")
public class YourActivity extend Activity {
    ...
}

//跳转
ARouter.getInstance().build("/test/activity").navigation();

使用很方便,通过一个path就可以进行跳转了,那么原理是什么呢?

其实仔细思考下,就可以联想到,既然关键跳转过程是通过path跳转到具体的activity,那么原理无非就是把pathActivity一一对应起来就行了。没错,其实就是通过注释,通过apt技术,也就是注解处理工具,把path和activity关联起来了。主要有以下几个步骤:

  • 代码里加入的@Route注解,会在编译时期通过apt生成一些存储path和activity.class映射关系的类文件
  • app进程启动的时候会加载这些类文件,把保存这些映射关系的数据读到内存里(保存在map里)
  • 进行路由跳转的时候,通过build()方法传入要到达页面的路由地址,ARouter会通过它自己存储的路由表找到路由地址对应的Activity.class
  • 然后new Intent方法,如果有调用ARouterwithString()方法,就会调用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生成索引文件,也就无法正常跳转了:

代码语言:javascript复制
//业务组件的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收割机。 积累也是一种力量。

0 人点赞