Android框架源码分析——以Arouter为例谈谈学习开源框架的最佳姿势

本文详细介绍了Android组件化框架ARouter的用途、使用方法、工作原理和源码分析。首先,文章阐述了ARouter在解决组件化问题中的作用,以及其与原生Android组件通信的区别。接着,讲解了ARouter的基本使用,包括如何进行界面跳转。然后,通过工作原理部分,探讨了ARouter如何实现组件间通信,分析了其执行流程。此外,还深入探讨了ARouter的初始化过程、源码架构和实现。最后,作者分享了在学习ARouter源码过程中收获的细节和思考,如按需加载、拦截器实现、Autowired参数解析等,以及如何将这些细节应用于实际开发中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

得意于众多项目和第三方库的开源,开发中使用几行代码即可实现复杂的功能,但使用只是源码库的搬运工,源码中真正牛逼的技术并不属于我们,所以对源码和开源库的学习成了Android开发者提升技能的必经之路,笔者也曾经认真学习了常用开源框架的原理和实现,足以在开发和面试中的问题,就此以为掌握了源码(有没有同道?),直到有一天自己去编写库,当面对框架设计、任务调度、任务并发、线程切换、缓存、文件等系列问题时,才发现自己的不足,也在反思自己的学习深度;其实框架中很多知识和代码都是经过时间的验证和优化过的,如:Glide的缓存、okhttp拦截实现、Retrofit的注解等,其细节完全可以帮助解决开发中的类似问题,源码的思想固然重要,但细节优秀的实现同样不容忽视,这里给出笔者总结的开源框架的学习方法:

  1. 了解开源框架的作用
  2. 掌握框架的使用方法
  3. 分析框架的工作原理
  4. 分析框架源码的架构和实现
  5. 深入框架细节分析功能模块的实现
  6. 总结收获

1、ARouter作用

谈起Arouter便不得不说组件化,随着项目的发展,开发的功能模块增多,项目和团队都会逐渐增大,即使分包和版本管理做的再好,还是无法避免在开发过程中所面临的问题:

  • 开发过程中编译和修改的过程中会变得更加复杂,编译事件明显变长
  • 整个项目为一个整体,代码牵一发而动全身,项目的维护难度将会增大;
  • 伴随开发团队也会增加,严重耦合的代码和业务造成冲突不断,极大降低开发效率

为了解决这些问题组件化应运而生,相信组件化的使用和优势开发者深有体会,它很针对性的解决了以上问题:

  • 组件可以独立开发、编译调试,缩短编译时间提高开发效率
  • 组件间的解耦和代码的隔离,使功能模块和开发团队之间互不影响

但世界上没有绝对完美的事,它带来方便的同时也带来了一个问题:

  • 组件解耦、代码隔离的同时也阻断了彼此的通信

那么实现组件间通信变成了首要要解决的问题,Android原生虽然可以实现脱离界面实现导航的目的,但真实使用时发现代码严重耦合,违背了我们组件化的目的,那么有没有一种简单易管理的通信方案呢?ARouter就是为此诞生,这里借用官方关于原生和路由的对比图:

关于ARouter的介绍这里提供一个官方的演讲内容:

2、ARouter的使用简介

知道了框架的作用,下面自然就是看看如何去使用,本文侧重于框架的源码和执行流程,不详细介绍框架的使用,因为下面分析源码的需要,这里只给出界面跳转使用,详细使用方法可以阅读Arouter的项目介绍:

  1. 实现界面跳转:根据跳转的功能需求,ARouter提供以下界面跳转方法
  • 普通界面跳转
ARouter.getInstance().build("/login/activity").navigation()
  • 携带Key—Value参数传递
//ARouter提供withString()方法,参数传入对应的Key、Value
 ARouter.getInstance().build("/login/activity")
                 .withString("Name", "USer")
                 .withInt("Age", 10)
                 .navigation()

//使用Autowired注解自动转换,参数name为传递参数的Key(当变量名和Key相同时可不设置name)
@Autowired(name = "Name")
@JvmField var name : String? = null
@Autowired(name = "Age")
@JvmField var age = 0

3、ARouter工作原理

  • ARouter的工作流程图

一行代码就搞定了组件间的通信,是不是充满了疑惑和期待?下面看看这一行代码究竟如何路由起来的?本文的分析基于编写的组件化Demo中的ARouter的使用,这里不对它的编写和使用做介绍,只分析它编译生成的文件和执行流程进行分析,本篇以Activity执行为例分析源码,先看一下项目的结构和编译生成的文件:

  • 项目结构:包含base、app、login、share、componenbase组件
  • 编译文件:编译生成routes和modularization包

3.1、ARouter执行流程

由上面使用知道,界面的路由跳转有一行代码完成,那流程的分析也就从这行神奇的代码开始:

ARouter.getInstance().build("/login/activity").navigation()
  • build(String path)

ARouter.getInstance()单利获取ARouter实例,在ARouter.build()方法中使桥接模式将任务交给_ARouter的build()方法,方法中重点的就是最后一句话,直接调用build()创建PostCard实例:

//_ARouter.build()
protected Postcard build(String path, String group) {
        if (TextUtils.isEmpty(path) || TextUtils.isEmpty(group)) {
            throw new HandlerException(Consts.TAG + "Parameter is invalid!");
        } else { ......}
            return new Postcard(path, group);//创建PostCard保存路径和group
        }
    }
  • PostCard.navigation():build()方法只创建了一个PostCard实例,貌似所有的任务都留给了navigation
protected Object navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
    try {
        LogisticsCenter.completion(postcard);//执行复杂的解析和配置
    } catch (NoRouteFoundException ex) {......}
        if (null != callback) {
            callback.onLost(postcard);//如果回调Callback不为null,回调onLast()
        } 
    ......
    if (!postcard.isGreenChannel()) { //如果没有设置绿色通道,要回调事件拦截
    ......
    } else {
        return _navigation(context, postcard, requestCode, callback);
    }
    return null;
}

整个流程执行到这里,好像就做了三件事,但这三件事却完成了整个的导航过程:

  1. 在build()中创建PostCard实例储存路径
  2. 调用complete()方法解析postCard
  3. 调用_navigation()执行界面的跳转
  • LogisticsCenter.completion(postcard)

在看详细的代码之前,先介绍下源码中出现的RouteMeta和Warehouse两个类,很容易看出这两个类都是保存数据的类:

  1. RouteMeta:保存每个跳转信息,如:路径、group、RouteType、优先级、参数等信息
  2. Warehouse:主要在初始化时缓存注解的Activity、IProvider、IInterceptor,主要用于缓存所有的路由信息
class Warehouse {
    //保存group对应的IRouteGroup文件类
    static Map<String, Class<? extends IRouteGroup>> groupsIndex = new HashMap<&g
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值