写点什么

滴滴开源 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:002548

评论

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

【架构学习10】——毕业总结

tiger

架构实战营

位运算小妙招-求二进制序列中1的个数

芒果酱

c++ C语言 5月月更

趣学设计模式-代理模式

ZuccRoger

5月月更

明道云入选爱分析2022年两份低代码研究报告

明道云

赵海鹏:如何进行OpenHarmony音频特性架构设计和开发工作

OpenHarmony开发者

OpenHarmony 开发者故事 开发者说

【架构学习09】——电商秒杀系统

tiger

架构实战营

C语言_标准时间与秒单位的转换

DS小龙哥

5月月更

区间合并算法

工程师日月

算法 5月月更

沙利文发布《2021年中国数据库市场报告》:中国分布式数据库2021专利占全球76%

科技热闻

姐姐驾到 | 零基础小白如何学前端!

锋享前端

存储卷指标消失之谜 | K8S Internals 系列第二期

BoCloud博云

Kubernetes kubelet

投稿开奖丨云服务器ECS征文活动(2&3月)奖励公布

阿里云弹性计算

云服务器 征文投稿开奖 玩转ECS

MySQL__数据处理之查询

编程江湖

ptrace注入分析

小道安全

万亿储能的极限拉力赛

钛禾产业观察

得物技术消息中间件应用的常见问题与方案

得物技术

kafka 分布式 MQ 中间件 消息队列

网站开发进阶(五十四)jQuery获取父级元素、子级元素、兄弟元素方法汇总

No Silver Bullet

JQuery框架 5月月更

面试突击47:死锁产生的原因有哪些?

王磊

Java 面试 java面试

极狐GitLab入驻阿里云计算巢,共同提升云上开发体验

阿里云弹性计算

DevOps 计算巢

2021年证券类APP更新迭代检测专题分析(上)发布

易观分析

金融 券商App

vue 自从使用了组件,工作量减去了一半

CRMEB

共同推动基础软件根技术发展,华为与中国软件行业协会签署战略合作协议

科技热闻

数据湖揭秘—Delta Lake

阿里云大数据AI技术

sql spark 分布式计算 关系型数据库 存储

SAP 订单模型的编排方式概述

Jerry Wang

订单管理 订单 5月月更 b2b 编排系统

web技术支持| Web 客户端实现录音、录像

anyRTC开发者

前端 Web 音视频 WebRTC 视频通话

来自2022年的Python 网络爬虫补充知识,HTML+JSON+爬虫场景

梦想橡皮擦

5月月更

【LeetCode】乘积小于 K 的子数组Java题解

Albert

LeetCode 5月月更

GaussDB(for Influx)与开源企业版性能对比

华为云开发者联盟

数据库 开源 查询 写入 GaussDB(for Influx)

5 月 20 日,API 网关 Apache APISIX Summit ASIA 2022 重磅来袭

API7.ai 技术团队

开源 API网关 Apache APISIX APISIX 网关 APISIX Summit

为了让女朋友运动起来,小伙儿不仅买单车还设计了智能防盗单车锁

华为云开发者联盟

stm32 华为云IoT 智能防盗单车锁 蓝牙

互联网用户画像,精准营销,数仓有妙招

华为云开发者联盟

位图 GaussDB(DWS) 用户画像 精准营销 Roaringbitmap

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