美文网首页Android开发
ARouter基本使用(一)

ARouter基本使用(一)

作者: 因为我的心 | 来源:发表于2021-11-30 09:53 被阅读0次

1、前言:

首先借用阿里云栖社区的一段话:我们所使用的原生路由方案一般是通过显式intent和隐式intent两种方式实现的(这里主要是指跳转Activity or Fragment)。在显式intent的情况下,因为会存在直接的类依赖的问题,导致耦合非常严重;而在隐式intent情况下,则会出现规则集中式管理,导致协作变得非常困难。一般而言配置规则都是在Manifest中的,这就导致了扩展性较差。除此之外,使用原生的路由方案会出现跳转过程无法控制的问题,因为一旦使用了StartActivity()就无法插手其中任何环节了,只能交给系统管理,这就导致了在跳转失败的情况下无法降级,而是会直接抛出运营级的异常。这时候如果考虑使用自定义的路由组件就可以解决以上问题,比如通过URL索引就可以解决类依赖的问题;通过分布式管理页面配置可以解决隐式intent中集中式管理Path的问题;自己实现整个路由过程也可以拥有良好的扩展性,还可以通过AOP的方式解决跳转过程无法控制的问题,与此同时也能够提供非常灵活的降级方式。
ARouter官方项目地址

二、基本使用:

1、添加依赖

android {
    defaultConfig {
        //必须添加的
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [AROUTER_MODULE_NAME: project.getName()]
            }
        }
    }
}

dependencies {
    // Replace with the latest version
   //版本依赖
   compile'com.alibaba:arouter-api:1.3.1'
   annotationProcessor'com.alibaba:arouter-compiler:1.1.4'
}
// --Kotlin如下使用--
implementation "com.alibaba:arouter-api:1.5.1"
kapt "com.alibaba:arouter-compiler:1.5.1"
kapt "com.alibaba:arouter-annotation:1.0.6"
图片.png

2、初始化

官方建议我们在Application里面进行ARouter初始化,于是乎就有了以下代码:

if (isDebug()) {        
    ARouter.openLog();     // Print log
    ARouter.openDebug();   
}
ARouter.init(this);
图片.png

然后别忘记了在清单文件里面配置自定义的Application和我们的Activity。

项目依赖导入和初始化就已经完成了,下面就开始正式的功能使用以及简单的封装。

3、开始使用:

1)首先:在Activity/Fragment类上面写上 Route path 注解。

注意:这里的路径需要注意的是至少需要有两级,/xx/xx

2)然后:在Activity/Fragment类里面进入Arouter 注入,也就是:ARouter.getInstance().inject(this);

3)接着:目标的Activity类上面需要声明Route path 注解,以此对应(跳转如果不对应路径,框架会Toast说路径不匹配)

上述说明的简单使用如下图:

图片.png

理论上来说,如果只是进行简单的跳转页面,

ARouter.getInstance().build(“目标界面对应的路径”).navigation(); 就这样一行代码即可完成跳转界面。

好了,看到这里我们就会发现,路径的标签如果多了就不是很好管理,(所以更好的选择是写一个类,在这个类里面统一管理和维护路径标签,不仅利于维护也方便后期拓展,看到路径就一目了然,哇~这个路径对应的是登录界面,这个路径对应的是详情界面);其次,每个页面的注入,也就是ARouter.getInstance().inject(this);这句代码出现的几率会写的很多,(而且一般的常规逻辑是有注入就有解绑或者释放资源)所以我们应该简单封装起来提高效率

4、简单封装

首先是路径管理:

图片.png

然后是注入封装:

这里多提一嘴,优秀的第三方框架如果一般有注入或者绑定的API,那与之对应的一般就会有释放或者解绑资源的API。(这样做的本质是优化内存)其中, ARouter.getInstance().destroy( ) ; 这个API一目了然,就是释放资源的API。下面就是开始注入和释放资源的封装:

图片.png

笔者在Activity的基类里面通过生命周期进行了注入和解绑,但是项目运行后发现了一个问题,就是如果在onDestroy()里面调用了 ARouter.getInstance().destroy( ) ; 在进入目标Activity之后,然后按back键返回原界面的时候,APP会报错崩溃,下面是崩溃日志:

图片.png

仔细一看,初始化有问题?在前面我们说到在自定义Application里面已经初始化了ARouter,且在清单文件里面配置了自定义的Application,但是依旧提示没有初始化,这就纳了个闷?然后想了想,可能是 ARouter.getInstance().destroy( );这行代码的使用位置可能用错了。然后既然是在Application里面进行的初始化,那么就可以将这行释放资源的代码,写在Application生命周期的onTerminate( )里面,果不其然,项目运行后就没什么问题了。当然,这是我自己的思路,有更好的意见和想法请在评论区指出,谢谢。

图片.png

封装完毕了路径标识以及注入释放等基本功能,我们回到ARouter的基本使用:

5、简单页面跳转

如果只是简单的页面跳转,一行代码即可完成,如下图

图片.png

其中,build里面是页面的标签路径,对应的就是目标Activity的这里,也就是类注释标签路径要一致:

图片.png

注意:不要忘了在清单文件里面配置Activity。

6、带参数的界面跳转

  • 带参数的跳转是很常见的功能,Android可以通过Bundle去传递参数,如果使用ARouter框架,它传递参数通过以下去操作:
  • ARouter传递对象的时候,首先该对象需要Parcelable或者Serializable序列化,可能Parcelable这个序列化大家觉得手写起来比较麻烦,但是Android Studio已经有一些插件帮我们自动生成Parcelable序列化了(因为Android用Parcelable序列化优势会更加明显一些)
  • 字符串、char、int等基本数据类型当然都是可以传递的
  • 当然,它也可以直接传Bundle、数组、列表等很多对象,传递类型如下图
图片.png

携带参数的界面跳转,简单使用如下图

图片.png

其中,第一个参数代表的是参数的key,第二个参数对应的是我们要传递的属性值,也就是value

那么目标界面如何获取传递过来的值?

这个时候,我们需要在目标界面,使用Autowired注解,

图片.png

这样就可以获取到传递过来的值了

图片.png

值得注意的是,只有当 @Autowired(name = "test"),也就是key标签一致的情况下,才可以获取到对象的值,如果不写标签名,结果会为null,

图片.png

所以为了规避每一个可能会遇到的风险,建议在@Autowired里面 都写上与之对应具体的key名。

7、界面跳转动画

直接调用withTransition,里面传入两个动画即可(R.anim.xxx)

图片.png

8、使用URI进行跳转

ARouter框架也可以使用URI进行匹配跳转,代码也很少,只需匹配路径一致即可完成跳转:

图片.png

9、Fragment跳转

Fragment的跳转也可以参照Activity跳转,第一步依旧是先写上类注释,然后是强转,代码如下

图片.png

10、进阶用法之拦截器:

  • 拦截器是ARouter这一款框架的亮点。说起拦截器这个概念,可能印象更加深刻的是OkHttp的拦截器,OkHttp的拦截器主要是用来拦截请求体(比如添加请求Cookie)和拦截响应体(判断Token是否过期),在真正的请求和响应前做一些判断和修改然后在去进行操作,大抵这就是拦截器的简单概念。那么,ARouter框架的拦截器是怎么实现的?
  • ARouter的拦截器,是通过实现 IInterceptor接口,重写init()和process()方法去完成拦截器内部操作的。

首先我们定义两个拦截器:


图片.png 图片.png

首先,定义ARouter拦截器必须要使用Interceptor类注解。注解里面的 priority(也就是红色框) 这个是声明拦截器的优先级、里面的属性值是int类型。既然是定义优先级,我们这里定义2个拦截器来测试看看优先级是如何区分谁先谁后的?两个拦截器写完之后,运行下项目看下效果:

图片.png

结论 1:根据实验得知,使用Interceptor类注解的priority数值越小,越先执行,优先级越高。(四大组件中的广播,优先级的取值是 -1000到1000,数值越大优先级越高)

  • 那么,还有一种情况,如果两个拦截器定义的优先级都是一样的,那么谁的优先级会高?是根据类的字符串长度来判断嘛还是别的条件来判断的??
  • 首先,将上面的拦截器的优先级改成一样(都改成1),项目编译试试,结果发现项目就会直接报错!
图片.png

看下具体的错误原因:

图片.png

翻译过来就是他们使用了相同的优先级,所以:

结论 2:如果两个拦截器的优先级一样,项目编译就会报错。所以,不同拦截器定义的优先级属性值不能相同

我们到这两个拦截器里面加一点筛选条件的代码:

图片.png

将这段代码加进去之后,重新运行App,打印日志结果如下:

图片.png

为了方便看清运行的日志,我用三种颜色的箭头去对应。首先是两个拦截器的初始化,然后,调用了NavigationCallback这个回调函数里面的onFound(),然后执行了拦截器里面的process()方法;当拦截器的process()方法执行完毕以后,最终回调了NavigationCallback里面的onArrival()方法。拦截器的工作流程大抵就是这样。那么,NavigationCallback这个又是什么?实际上,NavigationCallback这个简单理解就是ARouter在路由跳转的过程中,我们可以监听路由的一个具体过程。它一共有四个方法:

图片.png

那么,这个回调里面的 Postcard 又是什么意思?点进去源码看看,类注释写的一目了然:

图片.png

红色框翻译过来的类注释就是:一个包含路线图的容器。
既然是路线图的容器,那肯定有些API会获取到相应的信息,

图片.png

通过Postcard可以获取到路径的组以及全路径,那么,路径的组(Group)又是什么?是这样,一般来说,ARouter在编译期框架扫描了所有的注册页面/字段/拦截器等,那么很明显运行期不可能一股脑全部加载进来,这样就太不和谐了。所以就使用分组来管理,我们的类标签里面的注释,对于group默认是 “ ”(空字符串)如下图:

图片.png

在 Group简单使用 这张图上面,根据日志,打印了分组的信息,可以发现Group的值默认就是第一个 / /(两个分隔符) 之间的内容。

那么,我们也可以自定义分组,来进行界面跳转,所以ARouter又提供了一种解决方案:

11、自定义分组 实现跳转界面

如果使用自定义分组来跳转界面,只需要在源代码改动以下三个位置:

1:类注解新增 group,赋值我们自定义的组名,(依旧统一写在一个类里面这样便于管理)

图片.png

2:在build方法里面(这是一个方法重载),添加我们的与之对应的组名

图片.png

3:在被跳转的Activity里面的类注释,加上同样的组名

图片.png

通过上面三个步骤即可完成 自定义分组 来完成界面跳转


图片.png

通过日志显示,这里的组名已经被我们更改成自定义分组且成功完成了跳转。

2、ARouter如何实现类似startActivityForResult()?

这种应用场景也是很常见的,那ARouter该如何实现?

第一步:为了方便看效果,我们在第一个Activity设置requestCode 为123,

图片.png

第二步:需要在跳转的navigation方法(这是一个方法重载)里面的第二个参数,设置我们定义的requestCode,(通过匹配requestCode 来实现该功能)

图片.png

第三步:在第二个界面的setResult方法里面,写上对应的resultCode,这里就不展示Intent数据了

图片.png

综合上面三个步骤,项目编译运行,跳转到第二个界面然后返回上一个界面,日志成功打印:

图片.png

ARouter路由框架的基本使用就介绍到这里,源码分析请看第二篇。

探索Android路由框架-ARouter之深挖源码


参考:https://www.jianshu.com/p/6021f3f61fa6

相关文章

网友评论

    本文标题:ARouter基本使用(一)

    本文链接:https://www.haomeiwen.com/subject/storxrtx.html