ARouter简单入门和介绍

1.路由介绍

什么是路由框架?java

说简单点就是映射页面跳转关系的,固然它也包含跳转相关的一切功能android

为何使用ARouter?git

咱们先从适用场景来分析:github

  1. 动态跳转:通常来讲复杂的电商跳转多页面须要很强的灵活性,不少状况下是运营人员动态配置的下发活动页面,须要灵活的进行跳转。编程

  2. 组件化:随着业务量的不断增加,app也会不断的膨胀,开发团队的规模和工做量也会逐渐增大,面对所衍生的64K问题、协做开发问题等,app通常都会走向组件化。组件化就是将APP按照必定的功能和业务拆分红多个组件module,不一样的组件独立开发,组件化不只可以提供团队的工做效率,还可以提升应用性能。而组件化的前提就是解耦,那么咱们首先要作的就是解耦页面之间的依赖关系json

  3. Native与H5的问题:如今的APP不多是纯Native的,也不多会有纯H5的,通常状况下都是将二者进行结合。这时候就须要很是便捷而且统一的跳转方案,由于在H5中是没法使用StartActivity()跳转到Native页面的,而从Native跳转到H5页面也只能经过配置浏览器的方式实现api

  4. 其余等场景浏览器

原生跳转方式的不足安全

  • 显式跳转, Intent intent = new Intent(activity, XXActivity.class);
    因为须要直接持有对应class,从而致使了强依赖关系,提升了耦合度bash

  • 隐式跳转,譬如 Intent intent = new Intent(); intent.setAction(“com.android.activity.MY_ACTION”);
    action等属性的定义在Manifest,致使了扩展性较差
    规则集中式管理,致使协做变得很是困难。

  • 原生的路由方案会出现跳转过程没法控制的问题,由于一旦使用了StartActivity()就没法插手其中任何环节了,只能交给系统管理,这就致使了在跳转失败的状况下没法降级,而是会直接抛出运行时的异常。

2.ARouter的使用

1.添加框架的依赖和配置

在各个模块的build.gradle中添加编译参数和依赖的框架

android {
    defaultConfig {
    ...
    javaCompileOptions {
        annotationProcessorOptions {
        arguments = [ moduleName : project.getName() ]
        }
    }
    }
}

dependencies {
    // 替换成最新版本, 须要注意的是api
    // 要与compiler匹配使用,均使用最新版能够保证兼容
    compile 'com.alibaba:arouter-api:1.2.2'
    annotationProcessor 'com.alibaba:arouter-compiler:1.1.3'
    ...
}

// 旧版本gradle插件(< 2.2),可使用apt插件,在根build.gradle中配置方法
apply plugin: 'com.neenbedankt.android-apt'

buildscript {
    repositories {
        jcenter()    
    }

    dependencies {
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
    }
}复制代码

2.添加注解

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

3.初始化SDK

if (isDebug()) {           // 这两行必须写在init以前,不然这些配置在init过程当中将无效
    ARouter.openLog();     // 打印日志
    ARouter.openDebug();   // 开启调试模式(若是在InstantRun模式下运行,必须开启调试模式!线上版本须要关闭,不然有安全风险)
}
ARouter.init(mApplication); // 尽量早,推荐在Application中初始化复制代码

4.路由操做

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

// 2.跳转并携带参数
ARouter.getInstance().build("/test/activity2").navigation();
// 3.跳转并携带请求码
ARouter.getInstance().build("/test/activity2").navigation(this, requestCode);

// 4.URI跳转 
/*这种使用URi的方式中,URi的Scheme 和 host不影响结果,能够随便设,关键的是path
*  - build(URI)会把URI解析为path,并把当前URI存入PostCard
*  - build(String)构造的PostCard不存储URI*/
Uri testUriMix = Uri.parse("xx://xxx/test/activity2");
ARouter.getInstance().build(testUriMix)
                        .withString("name", "老王")
                        .withInt("age", 18)
                        .withBoolean("boy", true)
                        .withLong("high", 180)
                        .withString("url", "https://a.b.c")
                        .withParcelable("pac", testParcelable)
                        .withObject("obj", testObj)
                        .navigation();

// 5.跳转包含回调 单次降级策略能够在这里使用
ARouter.getInstance().build("/test/activity2").navigation(Context mContext, int requestCode, NavigationCallback callback);复制代码

5.配置自定义序列化方式

上诉的代码中有withObject进行传参,没有定义序列化方式是没法进行解析所以须要定义一个序列化方式,如下采用FastJson进行序列化

// 若是须要传递自定义对象,须要实现 SerializationService,并使用@Route注解标注(方便用户自行选择序列化方式),例如:
@Route(path = "/service/json")
public class JsonServiceImpl implements SerializationService {
    @Override
    public void init(Context context) {

    }

    @Override
    public <T> T json2Object(String text, Class<T> clazz) {
        return JSON.parseObject(text, clazz);
    }

    @Override
    public String object2Json(Object instance) {
        return JSON.toJSONString(instance);
    }
}复制代码

6.声明拦截器(拦截跳转过程,面向切面编程)

// 比较经典的应用就是在跳转过程当中处理登录事件,这样就不须要在目标页重复作登录检查
// 拦截器会在跳转之间执行,多个拦截器会按优先级顺序依次执行
@Interceptor(priority = 8, name = "测试用拦截器")
public class TestInterceptor implements IInterceptor {
    @Override
    public void process(Postcard postcard, InterceptorCallback callback) {
    ...
    callback.onContinue(postcard);  // 处理完成,交还控制权
    // callback.onInterrupt(new RuntimeException("我以为有点异常"));      // 以为有问题,中断路由流程

    // 以上两种至少须要调用其中一种,不然不会继续路由
    }

    @Override
    public void init(Context context) {
    // 拦截器的初始化,会在sdk初始化的时候调用该方法,仅会调用一次
    }
}复制代码

// 咱们常常须要在目标页面中配置一些属性,比方说"是否须要登录"之类的
// 能够经过 Route 注解中的 extras 属性进行扩展,这个属性是一个 int值,换句话说,单个int有4字节,也就是32位,能够配置32个开关
// 剩下的能够自行发挥,经过字节操做能够标识32个开关,经过开关标记目标页面的一些属性,在拦截器中能够拿到这个标记进行业务逻辑判断
@Route(path = "/test/activity", extras = Consts.XXXX)

7.经过依赖注入解耦:服务管理(一) 暴露服务

// 声明接口,其余组件经过接口来调用服务
public interface HelloService extends IProvider {
    String sayHello(String name);
}

// 实现接口
@Route(path = "/service/hello", name = "测试服务")
public class HelloServiceImpl implements HelloService {

    @Override
    public String sayHello(String name) {
    return "hello, " + name;
    }

    @Override
    public void init(Context context) {

    }
}复制代码

8.经过依赖注入解耦:服务管理(二) 发现服务

public class Test {
    @Autowired
    HelloService helloService;

    @Autowired(name = "/service/hello")
    HelloService helloService2;

    HelloService helloService3;

    HelloService helloService4;

    public Test() {
    ARouter.getInstance().inject(this);
    }

    public void testService() {
     // 1. (推荐)使用依赖注入的方式发现服务,经过注解标注字段,便可使用,无需主动获取
     // Autowired注解中标注name以后,将会使用byName的方式注入对应的字段,不设置name属性,会默认使用byType的方式发现服务(当同一接口有多个实现的时候,必须使用byName的方式发现服务)
    helloService.sayHello("Vergil");
    helloService2.sayHello("Vergil");

    // 2. 使用依赖查找的方式发现服务,主动去发现服务并使用,下面两种方式分别是byName和byType
    helloService3 = ARouter.getInstance().navigation(HelloService.class);
    helloService4 = (HelloService) ARouter.getInstance().build("/service/hello").navigation();
    helloService3.sayHello("Vergil");
    helloService4.sayHello("Vergil");
    }复制代码

小结

官方的文档Github很详细能够去看看

以上方式能够进行简单的入门使用了,下一步咱们从源码分析。

相关文章
相关标签/搜索