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

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

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

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

前言

  Intent intent = new Intent(mContext,XxxActivity.class);  intent.putExtra("key","value");  startActivity(intent);  Intent intent = new Intent(mContext,"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'}

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

总结

以上是内存溢出为你收集整理的[Alibaba-ARouter]浅谈简单好用的Android页面路由框架全部内容,希望文章能够帮你解决[Alibaba-ARouter]浅谈简单好用的Android页面路由框架所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1143831.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-31
下一篇2022-05-31

发表评论

登录后才能评论

评论列表(0条)

    保存