写点什么

滴滴开源 DRouter:一款高效的 Android 路由框架

  • 2021-06-04
  • 本文字数:3493 字

    阅读完需:约 11 分钟

滴滴开源DRouter:一款高效的Android路由框架

DRouter 简介


随着业务不断的发展,业务变的种类繁多,项目代码集中且耦合在一起,导致编译速度慢、开发效率低、维护困难、牵一发动全身。这时无论是从工程效能还是业务迭代稳定性的角度考虑,都需要把项目代码拆分成独立的组件。当组件拆分后,在没有代码耦合的前提下,如何快速、方便、灵活的进行组件间跳转、数据通信、生命周期控制是 DRouter 要解决的问题。


DRouter 支持的功能


  • 使用 URI 字符串导航 Activity、Fragment、View、RouterHandler,支持正则表达式

  • 回调式 onActivityResult

  • RouterHandler、Activity 支持等待异步完成(hold),并可设置超时时间

  • RouterHandler 指定执行线程

  • 注入拦截器,支持全局拦截器和局部拦截器,面向切面编程

  • 更为多样化的 Fragment 页面跳转能力

  • 使用接口或基类导航到实现类 Service 的 Class 以及实例

  • 支持 Service 别名以及多维过滤器查找

  • 导航 Service 可指定任意构造器、支持单例

  • 支持动态注册 RouterHandler、Service,绑定生命周期自动解绑

  • 简单易用的跨进程执行 RouterHandler、Service

  • 跨进程访问无需提前绑定、如同本地调用一样进行访问

  • 支持客户端进程和服务端进程自动重连

  • 支持 VirtualApk


为什么要开发 DRouter  


滴滴乘客端包容万象,拥有众多的业务和组件,早在 15 年就已经启动组件化重构。使用滴滴自研的基于 JavaSPI 插件技术,动态的生成从接口到实现的映射关系,完成了组件化的通信功能,并且应用到了整个滴滴的 Android 体系中。虽然 SPI 性能优良、使用便捷,但同时功能单一、支持的场景少也是一直存在的问题。随着组件化实践的常态化,急需要一款功能强大,适合滴滴的场景,定制化程度高的路由框架。

 

目前市面上已经存在几款路由框架了,比如 ARouter,WMRouter。不过滴滴业务繁多,平台化遍布各种场景,对路由的定制化需求强烈,很多功能市面上的路由是不支持的,比如:

 

  • ARouter 作为路由的先行者,由于开发较早,功能简单、同时路由查找过程性能损耗较大

  • WMRouter 在路由的性能上仍然有一定优化空间,同时没有导航到 Fragment/View、回调式 ActivityResult,使用 ServiceLoader 稍显繁琐且无法动态注册以及多维过滤

  • 现今没有一款路由框架对完整的跨进程和跨应用有较好的支持,这在滴滴定制车团队有着强诉求

  • 同时没有一款路由对 Fragment 提供更多的扩展能力,DRouter 在鸿鹄和车载屏项目以及更多 Fragment 的场景可以提供支持

 

基于以上问题,从 18 年开始自研了 DRouer 路由框架,为滴滴的平台化服务几十种场景。


DRouter 有哪些亮点


▍1 插件增量编译、多线程扫描,运行时异步加载路由表


路由表在编译期通过插件动态生成。插件会启动多线程同时异步处理所有的组件;增量扫描功能可以帮助开发者在第二次编译时,只对修改过的代码进行处理,极大地缩短路由表生成的时间。

 

在本人的开发机上测试,19 年滴滴乘客端扫描 5.5 万个类,全量需要不到 6s 的时间;如果是修改了 application 模块,增量扫描只需要处理修改的单类,耗时 0.4s 时间;如果是修改了 library 组件,增量扫描需要扫描整个 jar 包,根据 jar 包的大小时间会稍多一些,例如滴滴专快组件增量耗时 3.9s。

 

另外框架初始化的时候启动子线程去加载路由表,不阻塞主线程的执行,尽其所能提高效率。


▍2 完整的 Router 功能


支持使用 URI 字符串导航 Activity、Fragment、View、RouterHandler,支持正则表达式、回调式 onActivityResult、拦截器;

 

RouterHandler 还支持异步完成(不阻塞)、指定执行线程等等;

 

同时针对 Fragment,支持单 Page、栈 Page、ViewPager 三种形式的 Fragment 加载。


▍3 强大的 ServiceLoader 能力


DRouter 同样是基于 SPI 的理念,路由表会生成接口或基类对实现类的映射。

 

  • 获取实例时可以指定执行任意构造器、单例、优先级排序、自动拆解所有接口和基类作为 key

  • 可以通过 alias,以及任意数量多的维度对目标进行多维过滤

  • 动态注册


▍4 像调用本地方法一样跨进程通信和回调


无需编写繁琐的 aidl 文件实现跨进程调用,使用方式几乎等同本地导航 RouterHandler 和 Service,只需增加一些配置即可。

 

  • 不需要异步去 bindService 等待,同步执行

  • 支持跨应用

  • 替代反射,服务端使用本地方法执行,提高执行效率

  • 支持任意类型的对象跨进程传递,包括 Context、自定义类,支持 RemoteCallback 回调

  • 服务端异常崩溃重启后,客户端按需自动重新执行已发送的跨进程命令。


▍5 框架内部尽可能减少使用反射,提升性能


加载路由表、实例化路由元素、以及跨进程命令到达服务端后的分发这些常规应该使用反射的场景,使用预占位或动态生成代码来替换成 java 的 new 创建和显式方式执行,最大限度的去避免反射执行,提高性能。

 

考虑到功能的全面性,使用 ServiceLoader 时如指定非默认构造函数以及跨进程时传递自定义类,在框架内部会使用到反射,不过可以使用默认构造函数以及对跨进程对象实现 Parcelable 来避免。


▍6 动态下载与 api 匹配的 plugin,自升级


很多项目包括 DRouter 需要搭配 gradle 插件和 java 依赖来使用,正常来讲升级 java 依赖时大概率需要同时升级 gradle 插件,这在滴滴这种业务线繁多,各业务线除了有自己的组件同时又有自己的壳工程场景是一个非常痛的点。当业务线的组件因平台的同学在公共层升级了 java 依赖后,但又没有同时手动更新自己业务壳工程的 gradle 插件,大概率就会编译失败。

 

DRouter 利用 plugin-proxy 壳插件来解决这个问题,壳插件会在编译期自动检查 java 依赖的版本,同时获得应该匹配的插件版本。接着 plugin-proxy 会去下载这个匹配的 gradle 插件,并最终执行。这样就解决了因升级 java 依赖而 gradle 插件不匹配导致的编译问题。


▍7 无需手动添加混淆规则


DRouter 把混淆规则隐藏到了 java 依赖里,当启用混淆功能时会自动应用混淆规则。这样即使升级了 DRouter 版本也无需关心混淆规则是否需要升级。


DRouter 的原理和架构



整体架构分三层,自下而上是数据流层、组件层、开放接口层。


4.1 数据流层


数据流层是 DRouter 最重要的核心模块,这里承载着插件生成的路由表、路由元素、动态注册、以及跨进程功能相关的序列化数据流。所有的路由流转都会从这里取得对应的数据,进而流向正确的目标。


4.2 组件层


这一层是功能组件层,核心的路由分发、拦截器、生命周期、异步暂存和监控、ServiceLoader、多维过滤、Fragment 路由,以及跨进程命令打包等。


4.3 开放接口层


DRouter 在接口层做了大量的精简和优化,在灵活性和易用性方面做了很多权衡,主要目的是减少冗余 API,使框架更为简单的使用和接入。比如 Request 和 ServiceLoader 作为最核心的 API 方法数非常少,一些不常用的功能会放到 Extend 中。


▍RouterFlow



路由数据流从创建 Request 开始,通过 URI 在路由表中找出所有的结点,会按照 RouterHandler、UI 的顺序以及优先级顺序执行。每一个元素都可以定义自己的拦截器,这里的拦截器必须放行以后才能执行对应的结点;同时对于 RouterHandler 执行完又可以决定是否拦截后面所有的结点。当所有的结点执行完,且异步暂存态也都已释放,最终把结果回传给请求处。


▍ServiceFlow



ServiceLoader 既可以获取 Class 也可以获取对象实例,核心是路由表和过滤器,其中 FeatureMatcher 拥有多维过滤的功能。像滴滴这种多业务场景的应用,在使用 MVP 架构时对 P 的匹配至少会需要根据所在国家、订单业务线、订单状态三个维度来分别对应唯一的 Presenter,多维过滤就很容易解决这个问题。性能方面,对象实例化会根据构造器类型,利用插件生成的 RouterProxy 代码通过 new 来实例化无参对象(默认构造)或者反射实例化有参对象(非默认构造)。


▍RemoteFlow



DRouter 的跨进程功能是一大特色,左侧绿色代表客户端,自上而下会把所有的参数打包成命令,这里支持任意类型,框架内有一套完整的机制通过遍历集合、转换、组装,最后存储到 Parcel 里。利用 Authority 查找到服务端的 Provider 并随之利用此通道返回服务端的 Binder。


在服务端,也就是右侧的紫色,会自下而上把命令解包和分发。然后利用 DRouter 的路由 RouterHandler 和 ServiceLoader 的功能,使得客户端的命令最终在服务端执行。插件会在服务端生成一段代码,这段代码可以避免使用反射,提高整体的执行效率。

 

整个过程同步执行,使用简单、高效。


写在最后


DRouter 是一套功能完善、定制化程度高的路由框架,具有易于上手、架构清晰、性能优良的特点。现已成为滴滴不可或缺的基础组件之一。DRouter 作为组件化方案的践行者,将继续提升各个场景的支持能力,也欢迎各位开发者使用并提出宝贵的反馈意见。

 

GitHub 开源地址:https://github.com/didi/DRouter



头图:Unsplash

作者:DRouter

原文:https://mp.weixin.qq.com/s/c6E7NOKNWbTNYDLZRWAwSw

原文:滴滴开源 DRouter:一款高效的 Android 路由框架

来源:滴滴技术 - 微信公众号 [ID:didi_tech]

转载:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2021-06-04 08:002951

评论

发布
暂无评论
发现更多内容

数据仓库开发 SQL 使用技巧总结

C++后台开发

MySQL 数据库 sql 中间件 后端开发

React原理学习路线

郭明

ABAP-EXCEL上传下载

桥下本有油菜花

abap ABAPexcel

发现增长新动力,企业到底需要一朵什么样的云?

ToB行业头条

2022年中国娱乐直播市场年度综合分析

易观分析

直播市场

直播预告 | 多云时代如何建设企业云管理平台?

BoCloud博云

cmp 云管理平台 云管理

京东云联合Forrester咨询发布混合云报告 云原生成为驱动产业发展新引擎

京东科技开发者

云原生 数字化 科技 混合云 多云

Ampere Altra Max 提供可持续的高分辨率 H.265 编码

亚马逊云科技 (Amazon Web Services)

编码 Tech 专栏

低代码软件开发平台怎么选?

优秀

低代码开发 低代码平台

小李:“有没有特别简单的Python解密rsa的案例?”“还真有”

梦想橡皮擦

Python 爬虫 7月月更

一文了解 Nebula Graph 上的 Spark 项目

NebulaGraph

spark 图数据库 知识图谱 NebulaGraph

如何选择合适的体育场馆用LED显示屏

Dylan

LED显示屏 户外LED显示屏 led显示屏厂家

百度APP Android包体积优化实践(一)总览

百度Geek说

Java 安卓

IT小白也能轻松get日志服务---使用Nginx模式采集日志

云端explorer

nginx 运维 日志服务

医院怎么实现高效低成本运维?有什么软件可以满足吗?

行云管家

运维 IT运维 医院运维

可以 DIY 装修的商城系统,你也能拥有!

CRMEB

云图说丨数字资产链:您的数字资产产权保护神

华为云开发者联盟

区块链 云计算 开发 开发工具

LabView中禁用模块(属性节点)

一碗黄豆酱

短视频直播系统源码

开源直播系统源码

短视频源码 直播系统源码 短视频直播系统

李宏毅《机器学习》丨3. Gradient Descent(梯度下降)

AXYZdong

机器学习 7月月更

消息中间件

Damon

7月月更

SDL文字显示

柒号华仔

7月月更

Python图像处理丨三种实现图像形态学转化运算模式

华为云开发者联盟

Python 人工智能 AI 图像形态学

实操演示:如何用 ONES 制定 Scrum 迭代计划?

万事ONES

不是我说,不掌握这些坑,你敢用BigDecimal吗?

程序员小毕

Java 程序员 面试 后端 BigDecimal

LabView实验——温度检测系统(实验学习版)

一碗黄豆酱

LabView---信号发生器

一碗黄豆酱

服务器运维需要24小时在线吗?需要周末加班吗?

行云管家

服务器 IT运维

如何做好安全开发?

华为云开发者联盟

云计算 开源 安全 开发

如何在Docker部署安装ETL调度运维工具TASKCTL

敏捷调度TASKCTL

DevOps 大数据运维 Kafka ETL TASKCTL Docker 镜像

函数递归习题(easy版)

芒果酱

c++ C语言 7月月更

滴滴开源DRouter:一款高效的Android路由框架_文化 & 方法_滴滴技术_InfoQ精选文章