TheRouter
是一个 Kotlin 编写,用于 Android 模块化开发的一整套解决方案框架。
Github 项目地址与使用文档详见 https://github.com/HuolalaTech/hll-wp-therouter-android。
TheRouter 核心功能具备如下能力:
- 页面导航跳转能力(Navigator)
- 跨模块依赖注入能力(ServiceProvider)
- 单模块自动初始化能力(FlowTaskExecutor)
- 动态化能力(ActionManager)
- 模块AAR/源码依赖一键切换脚本
一、为什么要使用 TheRouter
路由是现如今移动端开发中必不可少的功能,尤其是企业级APP,可以用于将Intent
页面跳转的强依赖关系解耦,同时减少跨团队开发的互相依赖问题。
对于大型 APP 开发,基本都会选用模块化(或组件化)方式开发,对于模块间解耦要求更高。 TheRouter
是一整套完全面向模块化开发的解决方案,不仅能支持常规的模块依赖解耦、页面跳转,同时提供了模块化过程中常见问题的解决办法。例如:完美解决了模块化开发后由于组件内无法获取 Application
生命周期与业务流程,造成每次初始化与关联依赖调用都需要跨模块修改代码的问题。
1.1 TheRouter 四大能力
Navigator:
- 支持
Activity
和Fragment
- 支持
Path
与页面多对一关系或一对一关系,可用于解决多端path统一问题 - 页面
Path
支持正则表达式声明 - 支持
json
格式路由表导出 - 支持动态下发
json
路由表,降级任意页面为H5 - 支持任意
object
跨模块传递(无需序列化,且能保证对象类型) - 支持页面跳转拦截处理
- 支持自定义页面参数解析方式(例如将
json
解析为对象) - 支持使用路由跳转到第三方 SDK 中的
Activity
(Fragment
)
ServiceProvider:
- 支持跨模块依赖注入
- 支持自定义注入项的创建规则,依赖注入可自定义参数
- 支持自定义服务拦截,单模块
mock
调试 - 支持注入对象缓存,多次注入 只会new一次对象
FlowTaskExecutor:
- 支持单模块独立初始化
- 支持懒加载初始化
- 独立初始化允许多任务依赖(参考
Gradle Task
) - 支持编译期循环引用检测
- 支持自定义业务初始化时机,可以用于解决隐私合规问题
ActionManager:
- 支持全局回调配置
- 支持优先级响应与中断响应
- 支持记录调用路径,解决调试期观察者模式无法追踪
Observable
的问题
注: FlowTaskExecutor
、ActionManager
后续会作为可选能力,提供可插拔
或单独使用
的选项(预计10月份提供)。
二、路由方案
目前现有的路由基本上集中于两种能力的实现:页面跳转、跨模块调用,核心技术方案大体上如图:
- 开发阶段,对要使用路由的落地页或被调用方法添加注解标识。
- 编译期解析注解,生成一系列中间代码,待调用。
- 应用启动后调用中间代码完成路由的准备动作。大部分路由会额外通过
Gradle Transform
,在编译期做一次聚合,以提升运行时准备路由表的效率。 - 发起路由跳转时,本质上就是一次路由表遍历,通过uri获取到对应的落地页或方法对象,进行调用。
TheRouter
的页面跳转、跨模块调用也是如此,但是在设计上会有一些细节处理。
TheRouter
会在编译期根据注解生成 RouteMap__
开头的类,这些类中记录了当前模块的所有路由信息,也就是当前模块的路由表。
在最顶层的app
模块中,通过Gradle
插件,将所有aar、源码中的RouteMap__
开头的类统一集中到TheRouterServiceProvideInjecter
类中。
后续应用启动后,初始化路由时只需要执行TheRouterServiceProvideInjecter
类的方法,就能没有任何反射的加载到全部的路由表了。
加载以后的路由表会被保存到一个支持正则匹配的 Map
中,这也是TheRouter
允许多个path
对应同一个落地页的原因。每当发生页面跳转时,通过跳转时的path
,去Map
中获取到对应的落地页信息,再正常调用startActivity()
即可。
三、使用 TheRouter 页面跳转
3.1 声明路由项
如果一个页面(支持 Activity、Fragment)允许被路由打开,则需要使用注解 @Route
声明路由项,每个页面允许声明多个路由项,也就是一对多的能力,极大降低多端路由统一时的业务影响面。
参数释义
- path: 路由path 【必传】。
建议是一个url。path内支持使用正则表达式(为了匹配效率,正则必须包含反双斜杠\),允许多个path对应同一个Activity(Fragment)。 - action: 自定义事件【可选】。
一般用来打开目标页面后做一个执行动作,例如自定义页面弹出广告弹窗。 - description: 页面描述【可选】。
会被记录到路