【Android】初识路由框架及ARouter基本使用方法

路由框架

定义

路由框架是用于管理应用程序中不同组件(如页面、活动、模块等)之间导航和通信的工具。它通常提供了一种简化的方式来处理路由、参数传递和组件间的调用,使得开发者能够更加方便地管理应用的结构和导航。

路由框架的主要功能包括

  1. 页面导航:允许在不同的页面或组件之间进行跳转,通常支持传递参数。
  2. 路由配置:通过配置文件或注解方式定义路由规则,使得路由逻辑更加清晰。
  3. 参数解析:能够解析并传递参数,确保不同组件之间的数据共享。
  4. 解耦:降低了组件之间的耦合度,使得每个模块可以独立开发和测试。
  5. 动态路由:支持在运行时动态添加或修改路由,增强了灵活性。

为什么需要路由框架?

我们来简单说一下路由框架存在的意义:

  1. 显示Intent:项目庞大以后,类依赖耦合太大,不适合组件化拆分
  2. 隐式Intent:协作开发困难,调用的时候不知道调什么参数
  3. 每个注册了Scheme的Activity都可以直接打开,有安全风险
  4. AndroidMainfest集中式管理比较臃肿
  5. 无法动态修改路由,如果页面出错,无法动态降级
  6. 无法动态拦截跳转,例如未登录的情况下,打开登录页面,登录成功后接着打开刚才想打开的页面
  7. H5、Android、iOS地址不一样,不利于统一跳转
  8. 在一些复杂的业务场景下(比如电商),灵活性比较强,很多功能都是运营人员动态配置的,比如下发一个活动页面,我们事先并不知道具体的目标页面,但如果事先做了约定,提前做好页面映射,便可以自由配置。
  9. 简化代码,数行跳转代码精简成一行代码,这个大家应该都很容易理解,无非就是对代码块的封装。

简单实现

新建router-api模块,新建Router类:

public class Router {private static volatile Router mInstance;//使用 volatile 关键字防止指令重排序,确保在多线程环境中 mInstance 的正确性public static Router getInstance() {if (mInstance == null) {synchronized (Router.class) {if (mInstance == null) {mInstance = new Router();}}}return mInstance;}private static Map<String, Class<? extends Activity>> routers = new HashMap<>();public void register(String path, Class<? extends Activity> cls) {routers.put(path, cls);}public void startActivity(Activity activity, String path) {Class<? extends Activity> cls = routers.get(path);if (cls != null) {Intent intent = new Intent(activity, cls);activity.startActivity(intent);}}
}

public static Router getInstance() :这个方法用于获取 Router 类的实例。它首先检查 mInstance 是否为 null,如果是,则进入同步块。在同步块中再次检查 mInstance 是否为 null,如果是,则创建一个新的 Router 实例。这种方法称为双重校验锁,它确保了在多线程环境中只创建一个 Router 实例。

当我们想在另一个模块中使用Router的时候,需要先添加依赖:

implementation(project(":router-api"))

然后就可以进行使用了。

ARouter

简介

ARouter 是一个强大的 Android 路由框架,用于在 Android 应用中实现模块间的页面跳转、服务调用和依赖注入等功能。它主要用于简化和规范应用模块化开发中的页面导航,并提供了灵活的跳转配置和参数传递功能。

主要功能:

  • 页面跳转:ARouter 可以在模块化的应用架构中实现模块之间的页面跳转,而不需要直接引用其他模块,解耦页面间的依赖关系。
  • 服务管理:支持跨模块的服务调用,例如从一个模块中获取另一个模块提供的功能。
  • 依赖注入:支持在模块之间实现依赖注入,提供更灵活的服务调用方式。
  • 页面拦截:可以在跳转前进行拦截,例如进行登录校验、权限检查等。

使用方法

1. 配置

在build.gradle中进行配置:

implementation("com.alibaba:arouter-api:1.5.2")
annotationProcessor("com.alibaba:arouter-compiler:1.5.2")

2. 添加ARouter路由注解

@Route(path = "/test/RouteActivity")
public class RouteActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);}
}

上面的代码就是在目标Activity类上面声明Route path注解,以此对应,跳转如果不对应路径,框架会Toast说路径不匹配。

3. 初始化ARouter

在Activity同级包里,创建一个新的类RouteApplication.java继承Application:

public class RouteApplication extends Application {//ARouter调用开关private boolean isDebugARouter=true;@Overridepublic void onCreate() {super.onCreate();if (isDebugARouter) {// 打印日志ARouter.openLog();// 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)ARouter.openDebug();}ARouter.init(this);}
}

修改AndroidManifest.xml中内容,加入:

android:name=".RouteApplication"

4. 发起路由操作

 ARouter.getInstance().build("/test/RouteActivity").navigation();

build() 方法是 ARouter 中用于创建路由请求的核心方法。它会根据给定的路径(例如 "/test/RouteActivity")生成一个 Postcard 对象,该对象保存了目标页面或服务的所有路由信息,包括路径、分组和传递的参数等。

navigation() 方法是 ARouter 框架的核心方法,用于执行实际的跳转操作。它会根据 build() 方法中配置的路径和参数信息,完成页面跳转或服务调用的逻辑。

1>传递参数

可以通过 withXXX() 系列方法传递参数,支持常见的数据类型,例如 Stringintboolean 等:

ARouter.getInstance().build("/test/RouteActivity").withString("key", "value").withInt("age", 25).withBoolean("isStudent", true).navigation();

RouteActivity 中,可以通过 getIntent().getExtras() 方式获取这些参数,也可以使用 @Autowired 注解(需要 ARouter 的 inject() 方法)来自动注入参数:

ARouter.getInstance().build("/test/RouteActivity").withString("username", "xiaoduyyy").withInt("age", 19).navigation();
@Route(path = "/test/RouteActivity")
public class RouteActivity extends AppCompatActivity {@Autowiredpublic String username;  // 字段名与传递参数键名一致@Autowired(name = "age")  // 显式指定键名public int userAge;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_route);// 调用 ARouter 的 inject 方法,完成参数注入ARouter.getInstance().inject(this);// 验证参数是否成功注入Log.d("RouteActivity", "Username: " + username); // 输出:xiaoduyyyLog.d("RouteActivity", "User Age: " + userAge);  // 输出:19}
}
2>获取返回结果

1. 设置目标 Activity 的返回数据:

  • 在目标 Activity 中,通过 setResult() 方法设置返回的数据,并在完成操作后调用 finish() 结束页面。

2. 调用 navigation() 传递请求码:

  • 在调用的页面(比如 MainActivity)中,通过 ARouternavigation() 方法传递请求码来启动目标 Activity

3.onActivityResult() 中接收返回的数据:

  • 在调用页面的 onActivityResult() 方法中接收目标页面返回的数据。

假设在 ResultActivity 中完成一些操作后,需要返回结果给调用页面:

@Route(path = "/test/ResultActivity")
public class ResultActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_result);// 假设在按钮点击时完成操作并返回结果findViewById(R.id.btn_finish).setOnClickListener(v -> {Intent data = new Intent();data.putExtra("result_key", "This is the result data");setResult(RESULT_OK, data);  // 设置返回结果finish();  // 结束页面});}
}

在调用页面启动目标页面并接收返回结果:

public class MainActivity extends AppCompatActivity {private static final int REQUEST_CODE = 100;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 使用 ARouter 启动目标 Activity 并传递请求码findViewById(R.id.btn_start_activity).setOnClickListener(v -> ARouter.getInstance().build("/test/ResultActivity").navigation(this, REQUEST_CODE));}// 重写 onActivityResult 接收返回结果@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (requestCode == REQUEST_CODE && resultCode == RESULT_OK && data != null) {String result = data.getStringExtra("result_key");Log.d("MainActivity", "Result from ResultActivity: " + result);}}
}
3>指定启动动画
ARouter.getInstance().build("/test/RouteActivity").withTransition(R.anim.slide_in_right, R.anim.slide_out_left).navigation();

R.anim.slide_in_rightR.anim.slide_out_left分别是进入和退出动画资源。

4>创建 Intent 对象而不立即跳转
Intent intent = ARouter.getInstance().build("/test/RouteActivity").getIntent(this);
startActivity(intent);

使用 ARouter 构建 Intent,然后可以在需要的时候再进行跳转。

总结

在现代 Android 应用开发中,路由框架的使用已成为一种趋势,尤其是在进行模块化开发时,ARouter 提供了一个高效、灵活的解决方案。通过 ARouter,开发者不仅能够简化页面间的导航和参数传递,还能增强应用的可维护性与扩展性。它的动态路由和服务管理功能使得开发过程更加高效,避免了传统开发中因模块间依赖过于紧密而导致的问题。

希望本篇博客能对大家有所帮助!

参考:

Android路由框架用法大全主要是映射页面跳转关系,根据路由表将页面请求分发到指定页面。显示Intent:项目庞大以后 - 掘金


已经到底啦!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/462686.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Creo/Proe 入门基础教程(二)

本文章继续接着《Creo/Proe 入门基础教程&#xff08;一&#xff09;》的内容往下介绍&#xff1a; 2、绘制草图 草图绘制就是建立2D的截面图&#xff0c;然后以此截面生成拉伸、旋转等 特征实体。构成2D截面的要素有3个&#xff1a;2D几何图形&#xff08;Geometry&#xff0…

ZooKeeper 客户端API操作

文章目录 一、节点信息1、创建节点2、获取子节点并监听节点变化3、判断节点是否存在4、客户端向服务端写入数据写入请求直接发给 Leader 节点写入请求直接发给 follow 节点 二、服务器动态上下线监听1、监听过程2、代码 三、分布式锁1、什么是分布式锁?2、Curator 框架实现分布…

江协科技STM32学习- P30 FlyMCU串口下载STLink Utility

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

Java中的日期与时间对象:LocalDate类、LocalTime类、LocalDateTime类、DateTimeFormatter类

在 Java 中&#xff0c;LocalDate、LocalTime 和 LocalDateTime 是 java.time 包中的类&#xff0c;用于表示日期、时间和日期时间。这些类提供了不可变的日期与时间对象&#xff0c;是 Java 8 及以后版本中引入的一部分&#xff0c;用于替代旧的 java.util.Date 和 java.util.…

Java基于微信小程序的美食推荐系统(附源码,文档)

博主介绍&#xff1a;✌程序猿徐师兄、8年大厂程序员经历。全网粉丝15w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

杨辉三角形

大家好&#xff0c;今天给大家分享一下杨辉三角形是如何打印的&#xff0c;首先我们来看看它的原理。 我们先来看结果 1.如果把它看为一个二维数组&#xff08;包括后面的空格&#xff09;&#xff0c;那么它数字的这边是一个直角三角形&#xff0c;它的第一列和对角线都为1&a…

C语言进阶之我与指针的爱恨情仇(1)

一.前言 我们在初阶《指针》初阶C语言-指针-CSDN博客已经讲过了一些基础知识&#xff0c;知道了关于指针的一些概念-> 1.指针就是个变量&#xff0c;用来存放地址&#xff0c;地址唯一标识一块内存空间 2.指针的大小是固定的4/8个字节&#xff08;32位平台/64位平台&#xf…

构建灵活、高效的HTTP/1.1应用:探索h11库

文章目录 构建灵活、高效的HTTP/1.1应用&#xff1a;探索h11库背景这个库是什么&#xff1f;如何安装这个库&#xff1f;库函数使用方法使用场景常见的Bug及解决方案总结 构建灵活、高效的HTTP/1.1应用&#xff1a;探索h11库 背景 在现代网络应用中&#xff0c;HTTP协议是基础…

基于语音信号的说话人识别

基于语音信号的说话人识别 摘 要 语音是人类相互交流和通信最方便快捷的手段。如何高效地实现语音传输存储或通过 语音实现人机交互&#xff0c;是语音信号处理领域中的重要研究课题。语音信号处理涉及数字信号处理、语音学、语言学、生理学、心理学、计算机科学以及模式识别…

车载软件架构 --- 智能汽车软件

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 所有人的看法和评价都是暂时的&#xff0c;只有自己的经历是伴随一生的&#xff0c;几乎所有的担忧和畏惧…

实际案例说明用基于FPGA的原型来测试、验证和确认IP——如何做到鱼与熊掌兼得?

作者&#xff1a;Philipp Jacobsohn&#xff0c;SmartDV首席应用工程师 Sunil Kumar&#xff0c;SmartDV FPGA设计总监 本系列文章从数字芯片设计项目技术总监的角度出发&#xff0c;介绍了如何将芯片的产品定义与设计和验证规划进行结合&#xff0c;详细讲述了在FPGA上使用硅…

UiPath调用Python脚本的完整示例

一、主要步骤&#xff1a; 1、创建Python脚本 2、安装UiPath.Python.Activities库 3、使用方法&#xff1a; a、添加python作用域 b、加载python脚本 c、调用python方法 d、获取python对象 e、显示Python结果的消息对话框 二、详细步骤 1、安装UiPath.Python.Activities库 …

【简易进度条的实现】

独夜无伴守灯下&#xff0c;清风对面吹............................................................................................. 文章目录 前言 一、【行缓冲区的引入】 1、【问题提出】 2、【\r和\n】 3、【简易倒计时程序】 二、【简易进度条的实现】 process_bar.…

【已解决】cra 配置路径别名 @ 后,出现 ts 报错:找不到模块“@/App”或其相应的类型声明。ts(2307)

cra 配置路径别名 后&#xff0c;出现 ts 报错&#xff1a;找不到模块“/App”或其相应的类型声明。ts(2307) 然后可以在 tsconfig.json 中配置 baseUrl 和 paths &#xff1a; {"compilerOptions": {"target": "es5","lib": [&quo…

es拼音分词器(仅供自己参考)

github地址&#xff1a;https://github.com/infinilabs/analysis-pinyin&#xff08;各种版本&#xff0c;对接es版本&#xff09; 拼音分词器存在的问题&#xff1a; 1、是直接将每个字的拼音返回和一段话的拼音首字母返回&#xff0c;不能很好的分词。 2、不会保留中文&am…

为什么大家都在学数字孪生呢?

随着物联网&#xff0c;大数据、人工智能等技术的发展&#xff0c;新一代信息技术与制造业正在深度融合&#xff0c;人们与物理世界的交互方式正在发生转折性的变化。数字化转型正在成为企业的重要战略&#xff0c;而数字孪生则成为全新的焦点。 当下&#xff0c;在数字技术和…

【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,2-11

文件下载与邀请翻译者 学习英特尔开发手册&#xff0c;最好手里这个手册文件。原版是PDF文件。点击下方链接了解下载方法。 讲解下载英特尔开发手册的文章 翻译英特尔开发手册&#xff0c;会是一件耗时费力的工作。如果有愿意和我一起来做这件事的&#xff0c;那么&#xff…

LLM Observability: Azure OpenAI (一)

作者&#xff1a;来自 Elastic Vinay Chandrasekhar•Andres Rodriguez 我们很高兴地宣布 Azure OpenAI 集成现已全面上市&#xff0c;它提供了对 Azure OpenAI 服务性能和使用的全面可观察性&#xff01;另请参阅本博客的第 2 部分 虽然我们已经提供了对 LLM 环境的可视性一段…

HTML 基础标签——表格标签<table>

文章目录 1. `<table>` 标签:定义表格2. `<tr>` 标签:定义表格行3. `<th>` 标签:定义表头单元格4. `<td>` 标签:定义表格单元格5. `<caption>` 标签:为表格添加标题6. `<thead>` 标签:定义表格头部7. `<tbody>` 标签:定义表格…

第7章 内容共享

第 7 章 内容共享 bilibili学习地址 github代码地址 本章介绍Android不同应用之间共享内容的具体方式&#xff0c;主要包括&#xff1a;如何利用内容组件在应用之间共享数据&#xff0c;如何使用内容组件获取系统的通讯信息&#xff0c;如何借助文件提供器在应用之间共享文件…