Android路由框架-ARouter详解

简介: Android路由框架-ARouter详解文章大纲一、页面路由基本介绍1.什么是页面路由2.为什么要使用页面路由二、页面路由框架ARouter介绍1.常用功能介绍2.常见应用场景三、源码下载四、参考文章 一、页面路由基本介绍1.什么是页面路由  映射页面跳转关系,包含跳转相关的URL跳转及值传递、拦截器等功能。

Android路由框架-ARouter详解

文章大纲

一、页面路由基本介绍
1.什么是页面路由
2.为什么要使用页面路由
二、页面路由框架ARouter介绍
1.常用功能介绍
2.常见应用场景
三、源码下载
四、参考文章

 

一、页面路由基本介绍

1.什么是页面路由

  映射页面跳转关系,包含跳转相关的URL跳转及值传递、拦截器等功能。

2.为什么要使用页面路由

  在原始android开发中,当我们需要进行页面跳转时,正常写法如下:

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

Intent intent = new Intent(mContext, XXActivity.class);
intent.putExtra("key","value"); startActivityForResult(intent, 100); 

上述写法容易出现以下问题:

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

页面路由可以解决什么问题?

 

 

二、页面路由框架ARouter介绍

1.常用功能介绍

应用内页面跳转

添加依赖

 

温馨提示:api 的版本和 compiler 的版本号需要用最新的。最新的版本在 Github上可以找到。

重写Application并初始化ARouter

 
 

配置将要跳转的页面

 

进行简单的页面跳转

 

 

温馨提示:如果你想实现像 startActivityForResult() 功能,可以这样使用

 

运行结果如下:

 
 

携带参数进行页面跳转

 

温馨提示:支持数据类型如下:

//基础类型
.withString( String key, String value )
.withBoolean( String key, boolean value)
.withChar( String key, char value ) .withShort( String key, short value) .withInt( String key, int value) .withLong( String key, long value) .withDouble( String key, double value) .withByte( String key, byte value) .withFloat( String key, float value) .withCharSequence( String key, CharSequence value) //数组类型 .withParcelableArrayList( String key, ArrayList<? extends Parcelable > value) .withStringArrayList( String key, ArrayList<String> value) .withIntegerArrayList( String key, ArrayList<Integer> value) .withSparseParcelableArray( String key, SparseArray<? extends Parcelable> value) .withCharSequenceArrayList( String key, ArrayList<CharSequence> value) .withShortArray( String key, short[] value) .withCharArray( String key, char[] value) .withFloatArray( String key, float[] value) .withCharSequenceArray( String key, CharSequence[] value) //Bundle 类型 .with( Bundle bundle ) //Activity 跳转动画 .withTransition(int enterAnim, int exitAnim) //其他类型 .withParcelable( String key, Parcelable value) .withParcelableArray( String key, Parcelable[] value) .withSerializable( String key, Serializable value) .withByteArray( String key, byte[] value) .withTransition(int enterAnim, int exitAnim) 
 

运行程序,结果如下图所示:

 
 

路由监听
在路由跳转的过程中,我们可以监听路由的过程,只需要以下使用:

navigation(Context context, NavigationCallback callback)

NavigationCallback 的源码如下:

public interface NavigationCallback {

    /** * Callback when find the destination. * 找到了 * @param postcard meta */ void onFound(Postcard postcard); /** * Callback after lose your way. * 找不到了 * @param postcard meta */ void onLost(Postcard postcard); /** * Callback after navigation. * 跳转完了 * @param postcard meta */ void onArrival(Postcard postcard); /** * Callback on interrupt. * 被拦截了 * @param postcard meta */ void onInterrupt(Postcard postcard); } 

添加用于测试跳转的页面

 
 

在跳转的页面中添加监听代码

 

运行结果如下:

 
 
 

拦截器使用
添加需要跳转的页面

 

添加拦截器

 

在主页面进行跳转拦截测试

 

路由分组
在前面我们讲到在对 Activity1 做注解的时候,用到了

@Route(path = "/com/Activity1")
public class Activity1 extends AppCompatActivity {} 

  在 path 这个字符串里面,”com” 就代表组的标识;“Activity1” 代表是 Activity1 类的具体表示。组的标识和类的标识都可以自己定义的,需要记住的是组标识和类标识之间用斜杠来区分 ”\” .

什么是组?
这里就需要提下,ARouter框架是分组管理,按需加载。提起来很高深的样子呢!其实解释起来就是,在编译期框架扫描了所有的注册页面/服务/字段/拦截器等,那么很明显运行期不可能一股脑全部加载进来,这样就太不和谐了。所以就分组来管理,ARouter在初始化的时候只会一次性地加载所有的root结点,而不会加载任何一个Group结点,这样就会极大地降低初始化时加载结点的数量。比如某些Activity分成一组,组名就叫test,然后在第一次需要加载组内的某个页面时再将test这个组加载进来。

测试一下:

ARouter.getInstance()
       .build("/wxc/Activity1")
       .navigation(this, new NavCallback() {
            @Override
            public void onArrival(Postcard postcard) { String group = postcard.getGroup(); Log.e("zhao", "分组是: " + group); } }); 

结果是

07-27 17:32:17.880 19449-19449/com.router E/zhao: 分组是: wxc

ARouter 默认情况下的分组就是第一个 / / 之间的内容。

自定义分组
创建 CustomGroupActivity 并且添加 注解,并且指定路由分组。自定义分组的就是在原来的注解上添加 group 字段, 如下所示。

@Route(path = "/com/CustomGroupActivity" , group = "customGroup")
public class CustomGroupActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_custom_group); } } 

自定义分组,发起路由:第二个参数就是路由的分组

build(String path, String group)

具体实现如下所示:

 ARouter.getInstance().build("/com/CustomGroupActivity", "customGroup").navigation();

URL 跳转
web url 跳转流程图

 

创建URL 中间跳转页
创建 URLReceiveActivity

/**
 * URL 中转Activity
 */
public class URLReceiveActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView( R.layout.activity_url_receive ); //对URI 数据分发 Uri uri = getIntent().getData(); ARouter.getInstance().build(uri).navigation(this, new NavCallback() { @Override public void onArrival(Postcard postcard) { finish(); } }); } } 

URLReceiveActivity 添加注册

<activity android:name=".URLReceiveActivity">
      <!-- Schame --> <intent-filter> <data android:host="zhaoyanjun" 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> 

这里面的 host 、scheme 字段很重要。点击 url 会根据这两个字段会调起本地的 Activity 。

下面是一段 HTML 片段

<h2>1:URL普通跳转</h2>

<p><a href="arouter://zhaoyanjun/com/URLActivity1">arouter://zhaoyanjun/com/URLActivity1 </a> </p> <h2>2:URL普通跳转携带参数</h2> <p> <a href="arouter://zhaoyanjun/com/URLActivity2?name=alex&age=18&boy=true&high=180&obj=%7b%22name%22%3a%22jack%22%2c%22id%22%3a666%7d">arouter://zhaoyanjun/test/URLActivity2?name=alex&age=18&boy=true&high=180&obj={"name":"jack","id":"666"} </a> </p> 

注意 a 标签里面的 arouter://zhaoyanjun 分别代表着 scheme 、host ;/com/URLActivity1 就是目标 Activity 的注解。

如果需要接收 URL 中的参数,需要在 Activity 调用自动注入初始化方法;

ARouter.getInstance().inject(this);

需要注意的是,如果不使用自动注入,那么可以不写 ARouter.getInstance().inject(this),但是需要取值的字段仍然需要标上 @Autowired 注解,因为 只有标上注解之后,ARouter才能知道以哪一种数据类型提取URL中的参数并放入Intent中,这样您才能在intent中获取到对应的参数

具体的代码如下:

@Route(path = "/com/URLActivity2")
public class URLActivity2 extends AppCompatActivity{ private TextView textView; @Autowired String name; @Autowired int age; @Autowired boolean boy; @Autowired int high; @Autowired String obj ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ARouter.getInstance().inject(this); setContentView(R.layout.activity_url2); textView = (TextView) findViewById(R.id.tv); //解析参数 Bundle bundle = getIntent().getExtras(); String name1 = bundle.getString("name"); textView.setText("参数是: " + "name: " + name + " age: " + age + " boy: " + boy + " name1: " + name1 + " obj: " + obj.toString() ); } } 

效果图如下:

 

暴露服务
这里说到的服务不是Android四大组件中的Service,这里的服务是接口开发的概念,就是将一部分功能和组件封装起来成为接口,以接口的形式对外提供能力,所以在这部分就可以将每个功能作为一个服务,而服务的实现就是具体的业务功能。

我们先自定义一个接口 IService 并且继承 IProvider 。IService 接口里面有一个 sayHello() 方法,具体代码如下。

public interface IService extends IProvider { void sayHello(Context context ); } 

先定义一个 IService 的实现类 MyService 并且添加注解,代码如下

@Route(path = "/service/hello", name = "测试服务")
public class MyService implements IService { @Override public void sayHello( Context context ) { Toast.makeText( context , "hello", Toast.LENGTH_SHORT).show(); } @Override public void init(Context context) { } } 

发现服务,首先定义服务对象,并且添加注解,我们不需要知道接口的具体实现类。

@Autowired(name = "/service/hello")
IService service;

然后添加注解初始化,自动赋值。

ARouter.getInstance().inject(this);

最后我们调用 service 里面的 sayHello() 方法。

service.sayHello(this);

发现服务这个功能的特点在于,我们只需要知道接口,不需要关心接口的实现类,很好了实现了解耦。

路由关闭

ARouter.getInstance().destroy();

温馨提示:该功能慎用,搞不好整个app页面跳转就gg了。

代码混淆
如果我们使用了Proguard进行代码混淆,可以添加以下代码

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

2.常见应用场景

  1. 从外部URL映射到内部页面,以及参数传递与解析
    说明:该场景使用到了该文章的URL跳转和暴露服务功能,这样使得页面跳转功能很好的解耦,特别对于团队开发有很好管理作用。
  2. 跨模块页面跳转,模块间解耦
  3. 处理登陆、埋点等逻辑
    说明:该场景使用到了路由监听和拦截跳转等功能,在原始处理登陆、埋点等功能中,我们会先初始化Activity,再进行逻辑判断,这样会影响性能,如果我们使用了监听和拦截,那么在初始化新的Activity之前,我们可以先进行逻辑判断。

三、源码下载

链接:https://pan.baidu.com/s/1Y7Br3iKlDb-55VG1kAU70A
提取码:m0at

四、参考文章

    1. https://www.cnblogs.com/zhujiabin/p/7193400.html
    2. https://blog.csdn.net/x605940745/article/details/80583912
    3. https://blog.csdn.net/zhaoyanjun6/article/details/76165252
相关文章
|
13天前
|
前端开发 Java 编译器
当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
70 36
当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
|
14天前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
115 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
6月前
|
物联网 区块链 vr&ar
未来已来:探索区块链、物联网与虚拟现实技术的融合与应用安卓与iOS开发中的跨平台框架选择
【8月更文挑战第30天】在科技的巨轮下,新技术不断涌现,引领着社会进步。本文将聚焦于当前最前沿的技术——区块链、物联网和虚拟现实,探讨它们各自的发展趋势及其在未来可能的应用场景。我们将从这些技术的基本定义出发,逐步深入到它们的相互作用和集成应用,最后展望它们如何共同塑造一个全新的数字生态系统。
|
3月前
|
算法 JavaScript Android开发
|
4月前
|
Java 程序员 API
Android|集成 slf4j + logback 作为日志框架
做个简单改造,统一 Android APP 和 Java 后端项目打印日志的体验。
196 1
|
3月前
|
开发框架 Dart Android开发
安卓与iOS的跨平台开发:Flutter框架深度解析
在移动应用开发的海洋中,Flutter作为一艘灵活的帆船,正引领着开发者们驶向跨平台开发的新纪元。本文将揭开Flutter神秘的面纱,从其架构到核心特性,再到实际应用案例,我们将一同探索这个由谷歌打造的开源UI工具包如何让安卓与iOS应用开发变得更加高效而统一。你将看到,借助Flutter,打造精美、高性能的应用不再是难题,而是变成了一场创造性的旅程。
|
5月前
|
前端开发 Java 数据库
💡Android开发者必看!掌握这5大框架,轻松打造爆款应用不是梦!🏆
在Android开发领域,框架犹如指路明灯,助力开发者加速应用开发并提升品质。本文将介绍五大必备框架:Retrofit简化网络请求,Room优化数据库访问,MVVM架构提高代码可维护性,Dagger 2管理依赖注入,Jetpack Compose革新UI开发。掌握这些框架,助你在竞争激烈的市场中脱颖而出,打造爆款应用。
531 3
|
5月前
|
编译器 Android开发 开发者
带你了解Android Jetpack库中的依赖注入框架:Hilt
本文介绍了Hilt,这是Google为Android开发的依赖注入框架,基于Dagger构建,旨在简化依赖注入过程。Hilt通过自动化的组件和注解减少了DI的样板代码,提高了应用的可测试性和可维护性。文章详细讲解了Hilt的主要概念、基本用法及原理,帮助开发者更好地理解和应用Hilt。
138 8
|
6月前
|
设计模式 Java Android开发
探索安卓应用开发:从新手到专家的旅程探索iOS开发中的SwiftUI框架
【8月更文挑战第29天】本文旨在通过一个易于理解的旅程比喻,带领读者深入探讨安卓应用开发的各个方面。我们将从基础概念入手,逐步过渡到高级技术,最后讨论如何维护和推广你的应用。无论你是编程新手还是有经验的开发者,这篇文章都将为你提供有价值的见解和实用的代码示例。让我们一起开始这段激动人心的旅程吧!
|
6月前
|
Android开发
基于Amlogic 安卓9.0, 驱动简说(三):使用misc框架,让驱动更简单
如何使用Amlogic T972安卓9.0系统上的misc框架来简化驱动程序开发,通过misc框架自动分配设备号并创建设备文件,从而减少代码量并避免设备号冲突。
80 0
基于Amlogic 安卓9.0, 驱动简说(三):使用misc框架,让驱动更简单

热门文章

最新文章

  • 1
    如何修复 Android 和 Windows 不支持视频编解码器的问题?
  • 2
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 3
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
  • 4
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
  • 5
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
  • 6
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 7
    Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
  • 8
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 9
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
  • 10
    Android学习自定义View(四)——继承控件(滑动时ListView的Item出现删除按钮)