Github源码地址:https://github.com/alibaba/ARouter

一、功能介绍

  1. 支持直接解析标准URL进行跳转,并自动解析参数注入
  2. 支持多模块工程使用
  3. 支持添加多个拦截器,自定义拦截顺序
  4. 支持依赖注入,可单独作为依赖注入框架使用
  5. 支持InstantRun
  6. 支持MultiDex(Google方案)
  7. 映射关系按组分类、多级管理,按需初始化
  8. 支持用户指定全局降级与局部降级策略
  9. 页面、拦截器、服务等组件均自动注册到框架

二、典型应用

  1. 从外部URL映射到内部页面,以及参数传递与解析
  2. 跨模块页面跳转,模块间解耦
  3. 拦截跳转过程,处理登陆、埋点等逻辑
  4. 跨模块API调用,通过控制反转来做组件解耦

三、基础功能

  1. 添加依赖和配置

    android {
    defaultConfig {
    ...
    javaCompileOptions {
    annotationProcessorOptions {
    arguments = [ moduleName : project.getName() ]
    }
    }
    }
    } dependencies {
    compile 'com.alibaba:arouter-api:x.x.x'
    annotationProcessor 'com.alibaba:arouter-compiler:x.x.x'
    ...
    }
    // 旧版本gradle插件(< 2.2),可以使用apt插件,配置方法见文末'其他#4'
  2. 添加注解

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

    if (isDebug()) {
    ARouter.openLog(); // 打印日志
    ARouter.openDebug(); // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
    }
    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")
    .navigation();
  5. 添加混淆规则(如果使用了Proguard)

    -keep public class com.alibaba.android.arouter.routes.**{*;}
    -keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;}

四、进阶用法

  1. 通过URL跳转

    // 新建一个Activity用于监听Schame事件,之后直接把url传递给ARouter即可
    public class SchameFilterActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); Uri uri = getIntent().getData();
    ARouter.getInstance().build(uri).navigation();
    finish();
    }
    } // AndroidManifest.xml
    <activity android:name=".activity.SchameFilterActivity">
    <!-- Schame -->
    <intent-filter>
    <data
    android:host="m.aliyun.com"
    android:scheme="arouter"/> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/>
    <category android:name="android.intent.category.BROWSABLE"/>
    </intent-filter>
    </activity>
  2. 解析URL中的参数

    // 为每一个参数声明一个字段,并使用 @Autowired 标注
    @Route(path = "/test/activity")
    public class Test1Activity extends Activity {
    @Autowired
    public String name;
    @Autowired
    private int age;
    @Autowired(name = "girl") // 通过name来映射URL中的不同参数
    private boolean boy; @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ARouter.getInstance().inject(this); // ARouter会自动对字段进行赋值,无需主动获取
    Log.d("param", name + age + boy);
    }
    }
  3. 声明拦截器(拦截跳转过程,面向切面编程)

    // 比较经典的应用就是在跳转过程中处理登陆事件,这样就不需要在目标页重复做登陆检查
    // 拦截器会在跳转之间执行,多个拦截器会按优先级顺序依次执行
    @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初始化的时候调用该方法,仅会调用一次
    }
    }
  4. 处理跳转结果

    // 使用两个参数的navigation方法,可以获取单次跳转的结果
    ARouter.getInstance().build("/test/1").navigation(this, new NavigationCallback() {
    @Override
    public void onFound(Postcard postcard) {
    ...
    } @Override
    public void onLost(Postcard postcard) {
    ...
    }
    });
  5. 自定义全局降级策略

     // 实现DegradeService接口,并加上一个Path内容任意的注解即可
    @Route(path = "/xxx/xxx")
    public class DegradeServiceImpl implements DegradeService {
    @Override
    public void onLost(Context context, Postcard postcard) {
    // do something.
    } @Override
    public void init(Context context) { }
    }
  6. 为目标页面声明更多信息

    // 我们经常需要在目标页面中配置一些属性,比方说"是否需要登陆"之类的
    // 可以通过 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");
    }
    }

五、更多功能

  1. 初始化中的其他设置

    ARouter.openLog();      // 开启日志
    ARouter.openDebug(); // 使用InstantRun的时候,需要打开该开关,上线之后关闭,否则有安全风险
    ARouter.printStackTrace(); // 打印日志的时候打印线程堆栈
  2. 详细的API说明

    // 构建标准的路由请求
    ARouter.getInstance().build("/home/main").navigation(); // 构建标准的路由请求,并指定分组
    ARouter.getInstance().build("/home/main", "ap").navigation(); // 构建标准的路由请求,通过Uri直接解析
    Uri uri;
    ARouter.getInstance().build(uri).navigation(); // 构建标准的路由请求,startActivityForResult
    // navigation的第一个参数必须是Activity,第二个参数则是RequestCode
    ARouter.getInstance().build("/home/main", "ap").navigation(this, 5); // 直接传递Bundle
    Bundle params = new Bundle();
    ARouter.getInstance()
    .build("/home/main")
    .with(params)
    .navigation(); // 指定Flag
    ARouter.getInstance()
    .build("/home/main")
    .withFlags();
    .navigation(); // 觉得接口不够多,可以直接拿出Bundle赋值
    ARouter.getInstance()
    .build("/home/main")
    .getExtra(); // 使用绿色通道(跳过所有的拦截器)
    ARouter.getInstance().build("/home/main").greenChannal().navigation(); // 使用自己的日志工具打印日志
    ARouter.setLogger();
  3. 获取原始的URI

    String uriStr = getIntent().getStringExtra(ARouter.RAW_URI);
  4. 重写跳转URL

       // 实现PathReplaceService接口,并加上一个Path内容任意的注解即可
    @Route(path = "/xxx/xxx") // 必须标明注解
    public class PathReplaceServiceImpl implements DegradeService {
    /**
    * For normal path.
    *
    * @param path raw path
    */
    String forString(String path) {
    return path; // 按照一定的规则处理之后返回处理后的结果
    } /**
    * For uri type.
    *
    * @param uri raw uri
    */
    Uri forUri(Uri uri) {
    return url; // 按照一定的规则处理之后返回处理后的结果
    }
    }

六、其他

  1. 路由中的分组概念

    • SDK中针对所有的路径(/test/1 /test/2)进行分组,分组只有在分组中的某一个路径第一次被访问的时候,该分组才会被初始化
    • 可以通过 @Route 注解主动指定分组,否则使用路径中第一段字符串(/*/)作为分组
    • 注意:一旦主动指定分组之后,应用内路由需要使用 ARouter.getInstance().build(path, group) 进行跳转,手动指定分组,否则无法找到

      @Route(path = "/test/1", group = "app")
  2. 拦截器和服务的异同

    • 拦截器和服务所需要实现的接口不同,但是结构类似,都存在 init(Context context) 方法,但是两者的调用时机不同
    • 拦截器因为其特殊性,会被任何一次路由所触发,拦截器会在ARouter初始化的时候异步初始化,如果第一次路由的时候拦截器还没有初始化结束,路由会等待,直到初始化完成。
    • 服务没有该限制,某一服务可能在App整个生命周期中都不会用到,所以服务只有被调用的时候才会触发初始化操作
  3. Jack 编译链的支持

    • 因为不想让用户主动设置一堆乱七八糟的参数,在获取模块名的时候使用javac的api,使用了Jack之后没有了javac,只能让用户稍稍动动手了
    • 现在任何情况下都需要在build.gradle中配置moduleName了。。。。
  4. 旧版本gradle插件的配置方式

    apply plugin: 'com.neenbedankt.android-apt'
    
    buildscript {
    repositories {
    jcenter()
    } dependencies {
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
    }
    } apt {
    arguments {
    moduleName project.getName();
    }
    } dependencies {
    compile 'com.alibaba:arouter-api:x.x.x'
    apt 'com.alibaba:arouter-compiler:x.x.x'
    ...
    }

    注意:应用宝使用乐固加固后,ARouter的启动器会失效,所以启动器需要改成:

 public static void start(Context context, int communityId, String communityName) {
Intent starter = new Intent(context, CommunityApplyListActivity.class);
starter.putExtra("communityId", communityId);
starter.putExtra("communityName", communityName);
if (!(context instanceof Activity)) {
starter.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(starter);
}

【转载】ARouter-万能路由协议的更多相关文章

  1. 【转载】万能adapter

    adapter总是自己写,其实使用现成的框架会节省不少代码 原文地址:https://github.com/hongyangAndroid/baseAdapter base-adapter Andro ...

  2. 草根程序员如何进入BAT

        首页 最新文章 IT 职场 前端 后端 移动端 数据库 运维 其他技术 - 导航条 - 首页 最新文章 IT 职场 前端 - JavaScript - HTML5 - CSS 后端 - Pyt ...

  3. [转载]Ubuntu 安装 万能五笔 输入法

    原文地址:Ubuntu 安装 万能五笔 输入法作者:庖丁解牛 paul@paul-desktop:~/scripts$ cat ins-ibus-wnwb.sh #!/bin/sh set -e cd ...

  4. 【转载】可被路由的协议 & 路由协议 & 不可被路由的协议 的区别

    原文地址:可被路由的协议 & 路由协议 & 不可被路由的协议 的区别 术语routed protocol(可被路由的协议)和routing protocol(路由协议)经常被混淆.可被 ...

  5. 转载:对比Angular/jQueryUI/Extjs:没有一个框架是万能的

    Angular不能做什么?对比Angular/jQueryUI/Extjs 框架就好比兵器,你得明白你手里拿的是屠龙刀还是倚天剑,刀法主要是砍,剑法主要是刺.对于那些职业喷子和脑残粉,小僧送你们两个字 ...

  6. 打造android偷懒神器———RecyclerView的万能适配器

    转载请注明出处谢谢:http://www.cnblogs.com/liushilin/p/5720926.html 很不好意思让大家久等了,本来昨天就应该写这个的,无奈公司昨天任务比较紧,所以没能按时 ...

  7. 转载ali面

    引言 首先声明,不要再问LZ谁是林萧,林萧就是某著名程序员小说的主角名字. 写这篇文章的目的其实很简单,算是对之前LZ一篇文章的补充和完善. 之前LZ写过一篇<回答阿里社招面试如何准备,顺便谈谈 ...

  8. 转载:[转]如何学好3D游戏引擎编程

      [转]如何学好3D游戏引擎编程 Albert 本帖被 gamengines 从 游戏引擎(Game Engine) 此文为转载,但是值得一看. 此篇文章献给那些为了游戏编程不怕困难的热血青年,它的 ...

  9. Huge Page 是否是拯救性能的万能良药?

    本文将分析是否Huge Page在任何条件下(特别是NUMA架构下)都能带来性能提升. 本博客已经迁移至: http://cenalulu.github.io/ 为了更好的体验,请通过此链接阅读: h ...

随机推荐

  1. 怎样安装Command Line Tools in OS x Mavericks&Yosemite(Without xcode)--转载

    How to Install Command Line Tools in OS X Mavericks & Yosemite (Without Xcode) Mac users who pre ...

  2. Linux rpm yum 等安装软件

    任何程序都是先写代码,拿到源码去编译得到一个目标程序. 1  编译的过程复杂有需要准备编译的环境,和硬件有关,32位64位,内核的不同等等所以需要编译多次     Java特殊但是他需要安装jvm, ...

  3. 响应式布局之媒体查询 @media

    Media Queries,其作用就是允许添加表达式用以确定媒体的环境情况,以此来应用不同的样式表.换句话说,其允许我们在不改变内容的情况下,改变页面的布局以精确适应不同的设备. 媒体查询有两种玩法, ...

  4. 【洛谷 P3191】 [HNOI2007]紧急疏散EVACUATE(二分答案,最大流)

    题目链接 sb错误调了3hour+.. bfs预处理出每个\(.\)到每个\(D\)的最短距离. 二分时间\(t\),把每个\(D\)拆成\(t\)个点,这\(t\)个点两两连边,流量\(INF\)表 ...

  5. APP爬虫之Appium使用

    一.安装环境 Appium安装(windows版) 一.安装node.js 1.到官网下载node.js:https://nodejs.org/en/download/ 2.获取到安装文件后,直接双击 ...

  6. Oracle解锁scott账户

    Oracle安装完成之后scott账户默认是锁定的,登录的时候会提示账户已经被锁定: C:\Users\CC11001100>sqlplus scott/toor SQL*Plus: Relea ...

  7. C#里面中将字符串转为变量名

    public partial class Form1 : Form { string str = "spp"; public string spp = "very goo ...

  8. ubuntu永久修改主机名

    1.查看主机名 在Ubuntu系统中,快速查看主机名有多种方法:其一,打开一个GNOME终端窗口,在命令提示符中可以看到主机名,主机名通常位于“@”符号后:其二,在终端窗口中输入命令:hostname ...

  9. ajax技术整理总结(1)

    1.创建ajax对象 var xhr=new XMLHttpRequest(); 4.监听状态信息 xhr.onreadystatechange=function(){ //4接收完毕 ){ docu ...

  10. Java简单爬虫(一)

    简单的说,爬虫的意思就是根据url访问请求,然后对返回的数据进行提取,获取对自己有用的信息.然后我们可以将这些有用的信息保存到数据库或者保存到文件中.如果我们手工一个一个访问提取非常慢,所以我们需要编 ...