[Alibaba-ARouter]浅谈简单好用的Android页面路由框架

开发一款App,总会遇到各种各样的需求和业务,这时候选择一个简单好用的轮子,就可以事半功倍

前言

Intent intent = new Intent(mContext, XxxActivity.class); intent.putExtra("key","value"); startActivity(intent); Intent intent = new Intent(mContext, XxxActivity.class); intent.putExtra("key","value"); startActivityForResult(intent, 666);

上面一段代码,在Android开发中,最常见也是最常用的功能就是页面的跳转,我们经常需要面对从浏览器或者其他App跳转到自己App中页面的需求,不过就算是简简单单的页面跳转,随着时间的推移,也会遇到一些问题:

集中式的URL管理:谈到集中式的管理,总是比较蛋疼,多人协同开发的时候,大家都去AndroidManifest.xml中定义各种IntentFilter,使用隐式Intent,最终发现AndroidManifest.xml中充斥着各种Schame,各种Path,需要经常解决Path重叠覆盖、过多的Activity被导出,引发安全风险等问题 可配置性较差:Manifest限制于xml格式,书写麻烦,配置复杂,可以自定义的东西也较少 跳转过程中无法插手:直接通过Intent的方式跳转,跳转过程开发者无法干预,一些面向切面的事情难以实施,比方说登录、埋点这种非常通用的逻辑,在每个子页面中判断又很不合理,毕竟activity已经实例化了 跨模块无法显式依赖:在App小有规模的时候,我们会对App做水平拆分,按照业务拆分成多个子模块,之间完全解耦,通过打包流程控制App功能,这样方便应对大团队多人协作,互相逻辑不干扰,这时候只能依赖隐式Intent跳转,书写麻烦,成功与否难以控制。

另一个轮子

为了解决以上问题,我们需要一款能够解耦、简单、功能多、定制性较强、支持拦截逻辑的路由组件:我们选择了Alibaba的ARouter。

一、功能介绍

支持直接解析URL进行跳转、参数按类型解析到Bundle,支持Java基本类型(*) 支持应用内的标准页面跳转,API接近Android原生接口 支持多模块工程中使用,允许分别打包,包结构符合Android包规范即可(*) 支持跳转过程中插入自定义拦截逻辑,自定义拦截顺序(*) 支持服务托管,通过ByName,ByType两种方式获取服务实例,方便面向接口开发与跨模块调用解耦(*) 映射关系按组分类、多级管理,按需初始化,减少内存占用提高查询效率(*) 支持用户指定全局降级策略 支持获取单次跳转结果 丰富的API和可定制性 被ARouter管理的页面、拦截器、服务均无需主动注册到ARouter,被动发现 支持Android N推出的Jack编译链

二、不支持的功能

自定义URL解析规则(考虑支持) 不能动态加载代码模块和添加路由规则(考虑支持) 多路径支持(不想支持,貌似是导致各种混乱的起因) 生成映射关系文档(考虑支持)

三、典型应用场景

从外部URL映射到内部页面,以及参数传递与解析 跨模块页面跳转,模块间解耦 拦截跳转过程,处理登陆、埋点等逻辑 跨模块API调用,模块间解耦(注册ARouter服务的形式,通过接口互相调用)

四、基础功能

添加依赖和配置

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 { apt 'com.alibaba:arouter-compiler:x.x.x' compile 'com.alibaba:arouter-api:x.x.x' ... }

添加注解

// 在支持路由的页面、服务上添加注解(必选) // 这是最小化配置,后面有详细配置 @Route(path = "/test/1") public class YourActivity extend Activity { ... }

初始化SDK

ARouter.init(mApplication); // 尽可能早,推荐在Application中初始化

发起路由操作

// 1. 应用内简单的跳转(通过URL跳转在'中阶使用'中) ARouter.getInstance().build("/test/1").navigation(); // 2. 跳转并携带参数 ARouter.getInstance().build("/test/1") .withLong("key1", 666L) .withString("key3", "888") .navigation();

添加混淆规则(如果使用了Proguard)

-keep public class com.alibaba.android.arouter.routes.**{*;}

五、进阶用法

通过URL跳转

// 新建一个Activity用于监听Schame事件 // 监听到Schame事件之后直接传递给ARouter即可 // 也可以做一些自定义玩法,比方说改改URL之类的 // http://www.example.com/test/1 public class SchameFilterActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 外面用户点击的URL Uri uri = getIntent().getData(); // 直接传递给ARouter即可 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> <!-- App Links --> <intent-filter android:autoVerify="true"> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <data android:host="m.aliyun.com" android:scheme="http"/> <data android:host="m.aliyun.com" android:scheme="https"/> </intent-filter> </activity>

使用ARouter协助解析参数类型

// URL中的参数会默认以String的形式保存在Bundle中 // 如果希望ARouter协助解析参数(按照不同类型保存进Bundle中) // 只需要在需要解析的参数上添加 @Param 注解 @Route(path = "/test/1") public class Test1Activity extends Activity { @Param // 声明之后,ARouter会从URL中解析对应名字的参数,并按照类型存入Bundle public String name; @Param private int age; @Param(name = "girl") // 可以通过name来映射URL中的不同参数 private boolean boy; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); name = getIntent().getStringExtra("name"); age = getIntent().getIntExtra("age", -1); boy = getIntent().getBooleanExtra("girl", false); // 注意:使用映射之后,要从Girl中获取,而不是boy } }

开启ARouter参数自动注入(实验性功能,不建议使用,正在开发保护策略)

// 首先在Application中重写 attachBaseContext方法,并加入ARouter.attachBaseContext(); @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); ARouter.attachBaseContext(); } // 设置ARouter的时候,开启自动注入 ARouter.enableAutoInject(); // 至此,Activity中的属性,将会由ARouter自动注入,无需 getIntent().getStringExtra("xxx")等等

声明拦截器(拦截跳转过程,面向切面搞事情)

// 比较经典的应用就是在跳转过程中处理登陆事件,这样就不需要在目标页重复做登陆检查 // 拦截器会在跳转之间执行,多个拦截器会按优先级顺序依次执行 @Interceptor(priority = 666, name = "测试用拦截器") public class TestInterceptor implements IInterceptor { /** * The operation of this interceptor. * * @param postcard meta * @param callback cb */ @Override public void process(Postcard postcard, InterceptorCallback callback) { ... callback.onContinue(postcard); // 处理完成,交还控制权 // callback.onInterrupt(new RuntimeException("我觉得有点异常")); // 觉得有问题,中断路由流程 // 以上两种至少需要调用其中一种,否则会超时跳过 } /** * Do your init work in this method, it well be call when processor has been load. * * @param context ctx */ @Override public void init(Context context) { } }

处理跳转结果

// 通过两个参数的navigation方法,可以获取单次跳转的结果 ARouter.getInstance().build("/test/1").navigation(this, new NavigationCallback() { @Override public void onFound(Postcard postcard) { ... } @Override public void onLost(Postcard postcard) { ... } });

自定义全局降级策略

// 实现DegradeService接口,并加上一个Path内容任意的注解即可 @Route(path = "/xxx/xxx") // 必须标明注解 public class DegradeServiceImpl implements DegradeService { /** * Router has lost. * * @param postcard meta */ @Override public void onLost(Context context, Postcard postcard) { // do something. } /** * Do your init work in this method, it well be call when processor has been load. * * @param context ctx */ @Override public void init(Context context) { } }

为目标页面声明更多信息

// 我们经常需要在目标页面中配置一些属性,比方说"是否需要登陆"之类的 // 可以通过 Route 注解中的 extras 属性进行扩展,这个属性是一个 int值,换句话说,单个int有4字节,也就是32位,可以配置32个开关 // 剩下的可以自行发挥,通过字节操作可以标识32个开关 @Route(path = "/test/1", extras = Consts.XXXX)

使用ARouter管理服务(一) 暴露服务

/** * 声明接口 */ public interface IService extends IProvider { String hello(String name); } /** * 实现接口 */ @Route(path = "/service/1", name = "测试服务") public class ServiceImpl implements IService { @Override public String hello(String name) { return "hello, " + name; } /** * Do your init work in this method, it well be call when processor has been load. * * @param context ctx */ @Override public void init(Context context) { } }

使用ARouter管理服务(二) 发现服务

1. 可以通过两种API来获取Service,分别是ByName、ByType

IService service = ARouter.getInstance().navigation(IService.class); // ByType IService service = (IService) ARouter.getInstance().build("/service/1").navigation(); // ByName service.hello("zz");

2. 注意:推荐使用ByName方式获取Service,ByType这种方式写起来比较方便,但如果存在多实现的情况时,SDK不保证能获取到你想要的实现

使用ARouter管理服务(三) 管理依赖

可以通过ARouter service包装您的业务逻辑或者sdk,在service的init方法中初始化您的sdk,不同的sdk使用ARouter的service进行调用,每一个service在第一次使用的时候会被初始化,即调用init方法。

这样就可以告别各种乱七八糟的依赖关系的梳理,只要能调用到这个service,那么这个service中所包含的sdk等就已经被初始化过了,完全不需要关心各个sdk的初始化顺序。

六、更多功能

初始化中的其他设置

ARouter.openLog(); // 开启日志 ARouter.printStackTrace(); // 打印日志的时候打印线程堆栈

详细的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 Github链接

最新版本

arouter-annotation : 1.0.0 arouter-compiler : 1.0.1 arouter-api : 1.0.2

Gradle依赖

dependencies { apt 'com.alibaba:arouter-compiler:1.0.1' compile 'com.alibaba:arouter-api:1.0.2' }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

时间: 2024-08-02 23:27:57

[Alibaba-ARouter]浅谈简单好用的Android页面路由框架的相关文章

浅谈简单工作流设计——责任链模式配合策略与命令模式的实现

本文以项目中的一个工作流模块,演示责任链模式.策略模式.命令模式的组合实现! 流程简介 最近在做的一个项目,涉及到的是一个流程性质的需求.关于工程机械行业的服务流程:服务任务流程和备件发运流程. 项目之初,需求不是很清晰,算是演化模型吧.先出一个简单版本,然后根据用户的使用情况,再进一步探测新需求.所以也就是说这两个流程中的每一步暂时都不是固定的,而应该是可配置.可增减的. 目前暂定的两个流程示意图如下: 以上为两个流程的大致过程,当然实际过程中,可能还要走其他的流程. 但是,仔细分析,你会看到

浅谈简单分析SEO业界三大知名网站

直接入正题,今天我说下三个案例,做下网站最基本类的分析,以搜索"SEO"这个关键词,一个是搜外论坛子目录bbs,顶级域名在第二页,可能因为之前的改版所影响,二个是二级域名Chinaz站长工具,三是百度百科内页SEO词条,这三个站只要是在搜索引擎领域中搜索SEO,部分搜索引擎排名中全是前三甲,其中重点是百度百科内页SEO词条,这页在竞争对手的搜索引擎排名中展示中居前三,个别居第四,可见其权重之高,值得我们SEO重业人员好好研究. 一.网站基本信息 搜外seowhy: 域名时间5年零8个月

浅谈静态、伪静态和动态页面的优化方法

  对于网站网页都是由静态.伪静态和动态三种演而成的.而且现在站长都认为静态对于搜索引挚最为友好,也是最容易被收录.其实真的是这么回事吗?答案也未必如此吧.对于笔者而言,三种都有三种的好处,而且每种都有自已弊端.今天笔者分享下这三种网页的优化方法: 首先是静态网页的优化方法.站长都认为静态页面最符合搜索引挚优化,是不是真是如此排列了,笔者不这么认为,对于静态页面的好处就是可以让网页不存在漏洞,不像动态那样容易产生漏洞.但是静态页面占用的空间又是最大的,自然就要花费比较大的资金升级空间了.如果网站

浅谈千兆交换路由器的虚拟路由集群技术

一.引言: 当前,IP已经成为大部分骨干网络产品的路由协议.在部分网络环境,用户对网络的要求是很高的,任何停工和储运损耗都会对用户造成严重影响.例如: 1.Internet服务提供商提供Web主机设备,为了使得用户的Web服务器对公众总是有效的,必须保证用户99.9999%的正常运行时间. 2.过程控制应用必须能够适时访问它的控制的系统,否则可能会发生结果损失严重的控制: 3.有时,运行在IP主机上的应用会超时,如果业务运行对网络应用要求较高,这种超时会带来很坏影响. 越来越多的IP主机使用DH

浅谈如何让网址的内容页面也具有排名

除了搜索引擎能给网站带来流量网站流量,另一种方法就是固定用户也能够带来流量,每个新网站都是从搜索引擎来流量.其中搜索引擎流量的两种方式一种是用目标关键词,另一种是用长尾关键词.长尾关键词可以帮助那些网站主页关键词指数不是很高的词的网站来弥补流量. 它带来的比重流量占网站的绝大部分.一个新站要很长时间才能通过百度的考核期得到长尾关键词的流量,差不多要三个月之久,等不及的站长把网站给关了然后重新做另一个网站,这样有始无终的做网站,用于都不会成功.网站半年之后才会有目标关键词排名,前提是搜索量高的关键

浅谈网站死链出错404页面问题

网站出现死链是很平常的事情,绝大多数站长们都没有一个好的习惯,都没有去整理这个404出错页面.这方面既导致了用户体验失效,且导致SEO出现负面效果. 前几天,我一个朋友的客户网站有很多死链,原因就是因为之前好多内容都删除了,但是各引擎还有收录,并未更新,别人一点击那些死链,访问的页面根本不存在,因为他们是卖产品的,出现这种情况对他们整体权威度有很大的影响.我朋友管我要解决方法,最后帮他搞定了.其实这方面的东西在网上是很多的教程,只是疏忽了.我现在把深圳SEO站的404页面处理方法写出来,以供参考

使用Qt做一个简易音乐播放器[Phonon浅谈--续]

2010-2-13 使用Qt做一个简易音乐播放器[Phonon浅谈--续]   在第一篇Phonon浅谈中提及到了Phonon这个多媒体框架的一些基本知识,于是想着结合这些基本知识来实践一番,做一个简单的音乐播放器.   [步骤一] 新建一个Qt Gui工程,在建立过程中需要包含Phonon模块,之后生成文件如下图: Qt Gui工程会生成一个ui文件,在这里是mainwindow.ui.双击mainwindow.ui进行一番简单的布局,如下图: 关于这个ui界面,中央位置是一个QListWid

浅谈android组件化之ARouter简单使用

ARouter是阿里巴巴开源出来的一款android路由框架,github地址为 : https://github.com/alibaba/ARouter 至于ARouter的诸多好处我就不介绍了,这里主要讲解在项目组件化下,ARouter的一些简单使用 先贴上工程目录: 工程一共分为4个模块,基础组件app.基础服务(包涵路由服务)basecommonlibrary模块.业务模块libraryone.业务模块librarytwo; 在4个模块的gradle文件当中加入如下代码: android

浅谈python字符串方法的简单使用_python

学习python字符串方法的使用,对书中列举的每种方法都做一个试用,将结果记录,方便以后查询. (1) s.capitalize() ;功能:返回字符串的的副本,并将首字母大写.使用如下: >>> s = 'wwwwww' >>> scap = s.capitalize() >>> scap 'Wwwwww' (2)s.center(width,char); 功能:返回将s字符串放在中间的一个长度为width的字符串,默认其他部分用空格填充,否则使用c