- 移动开发
- 开发工具
【免费下载链接】RIBs
Uber's cross-platform mobile architecture framework - Android Repository
RIBs(Router、Interactor、Builder 的缩写)是 Uber 多个移动 App 背后的跨平台架构框架,专为拥有大量工程师与嵌套状态的大型移动应用而设计。本文以 Uber RIBs 官方仓库 README.md 为骨架,结合 libraries/ 目录下的核心源码与 tooling/ 工具链实现,系统讲解 RIBs 的架构理念、核心组件职责、与 MV*/VIPER 的本质区别,以及 Android 端的安装集成方式,帮助你理解并落地这套面向规模化团队的移动端架构方案。
RIBs 是什么:为大规模团队与嵌套状态而生的架构框架
RIBs 是 Uber 内部驱动多个移动 App 的跨平台架构框架(framework),而不仅仅是一种架构模式。框架与模式的区别在于:RIBs 不只是给出分层约定,还提供了具体的基类、注解处理器、路由生命周期管理、依赖注入约定以及配套 IDE 工具链。
RIBs 全称拆解如下:
- Router(路由):负责管理子 Router 的挂载(attach)与卸载(detach),是 RIB 树形结构的组织者;
- Interactor(交互器):承载业务逻辑,拥有独立的生命周期;
- Builder(构建器):负责组装依赖并构建 Router。
正如 libraries/rib-base/README.md 所描述的,这套框架被设计用于满足四个核心诉求:
| 特性 | 说明 |
|---|---|
| 跨平台共享架构 | iOS 与 Android 采用同构架构,两个平台团队可以互相 review 业务逻辑代码 |
| 可测试性与隔离性 | 每个 RIB 类职责单一(路由、业务、视图、创建),且大部分业务逻辑与子 RIB 逻辑解耦,易于独立测试与推理 |
| 提升开发效率的工具链 | 提供 IDE 插件(代码生成、静态分析)、内存泄漏检测与运行时集成工具 |
| 架构可规模化 | 已在同一代码库数百名工程师、数百个 RIB 的 App 中得到验证 |
业务逻辑驱动应用,而非视图树驱动:RIBs 与 MV*/VIPER 的本质区别
README 中明确指出:MVC、MVP、MVI、MVVM 与 VIPER 是架构模式,而 RIBs 是框架。其与基于 MV*/VIPER 的框架最核心的两点差异是:
- 业务逻辑驱动 App,而不是视图树驱动:与 MV*/VIPER 不同,一个 RIB不一定拥有 View。这意味着应用层级由业务逻辑决定,而非视图层级决定。
- 业务逻辑树与视图树相互独立:RIBs 将业务逻辑作用域的树形结构与视图层级解耦。应用可以拥有很深的业务逻辑树(隔离业务逻辑节点),同时保持较浅的视图层级,从而让布局、动画与转场变得简单。
在源码中可以看到这种"无视图 RIB"的直接支持:位于 libraries/rib-base/src/main/kotlin/com/uber/rib/core/Interactor.kt 的Interactor基类完全不依赖 Android View,而Router(见 Router.kt)同样只管理子 Router 的挂载卸载,不强制持有 View。只有当确实需要界面时,才引入 libraries/rib-android/src/main/kotlin/com/uber/rib/core/ViewRouter.kt 这类带视图的 Router 子类。这从实现层面印证了"业务逻辑树与视图树独立"的设计。
README 还列举了 RIBs 中其他一些新颖但也可用其他 MV*/VIPER 框架实现的点:
- 跨平台一致性:iOS 与 Android 架构保持同步;
- 大型 App/团队易采用:开源工具包括用于代码生成与静态代码分析的 IDE 插件;
- 对状态通信方式的强约定:使用DI 与 Rx。每个 RIB 定义自己的依赖以及需要从父 RIB 获取的依赖;满足子 RIB 父依赖的父组件,作为构造器依赖注入到子 Builder 中,形成层级化 DI 作用域。信息通过这些依赖在树中上下流动。
核心组件源码剖析:Router、Interactor、Builder 的职责边界
RIBs 将职责严格拆分为独立基类,每个类都可以独立测试。下面结合源码逐一说明。
Router:子路由的挂载与卸载
Router.kt 中,Router<I : InteractorType>是抽象基类,负责处理子 Router 的添加与移除。关键生命周期方法包括:
didLoad():Router 加载并初始化完成后调用(仅一次);willAttach()/willDetach():每次挂载/卸载时调用,用于可重复的 setup 与清理;attachChild(childRouter, tag):挂载子 Router,tag用于命名空间隔离子 Router 的保存状态 Bundle(源码见 Router.kt#L95-L142)。注意当tag重复时会通过Rib.getConfiguration().handleNonFatalWarning(...)发出警告;detachChild(childRouter):卸载子 Router,并调用ribRefWatcher.watchDeletedObject(interactor)监视被卸载对象,配合内存泄漏检测(源码见 Router.kt#L153-L186)。
从源码结构看,Router还负责状态保存:saveInstanceState会把 Interactor 状态与所有子 Router 的 Bundle 一并序列化到KEY_CHILD_ROUTERS/KEY_INTERACTOR命名空间下,并在重新挂载时恢复,这是 RIBs 支持进程重建的关键机制。
Interactor:承载业务逻辑的生命周期单元
Interactor.kt 中,Interactor<P : Any, R : Router<*>>是所有 Interactor 的基类,核心生命周期:
didBecomeActive(savedInstanceState):挂载(attach)时调用,Presenter 会自动加载;willResignActive():卸载(detach)时调用,进行清理;View 的移除是自动完成的;onSaveInstanceState(outState):保存状态。
同时Interactor实现了 InteractorType.kt 中的LifecycleScopeProvider<InteractorEvent>,通过ACTIVE -> INACTIVE的InteractorEvent生命周期流,与 AutoDispose 集成,使 Rx 订阅与协程作用域能自动跟随 RIB 生命周期销毁。
对于不使用字段注入的简单场景,BasicInteractor.kt 提供了直接以构造器传入 Presenter 的BasicInteractor,配合 BasicRouter.kt 即可工作。
Builder:组装依赖的工厂
Builder.kt 中,Builder<T : Router<*>, D>抽象类只做一件事:构建 Router。父 Router 通过构造器传入静态依赖;异步获取或动态创建的依赖,则通过 vends 一个 Router 的 build 方法传入。这正是 RIBs 层级化 DI 作用域的实现载体——每个子 Builder 都持有一个来自父组件的D类型依赖。
Presenter 与 Worker:辅助组件
- Presenter.kt:承载展示逻辑,拥有独立的
LOADED -> UNLOADED生命周期。源码注释坦诚地说明:它最初是为了在交互器与视图之间做模型转换而存在,但实践中如果 Presenter 与 Interactor 都能写复杂 Rx 逻辑,会让业务逻辑归属变得模糊——因此新代码应优先把复杂逻辑写在 Interactor 中; - Worker.kt 与 RibCoroutineWorker.kt:将管理器/辅助类绑定到 Interactor 生命周期的接口。注意
Worker已标记为Deprecated,官方推荐使用RibCoroutineWorker(replaceWith = ReplaceWith("RibCoroutineWorker"))。RibCoroutineWorker是函数式接口,可通过CoroutineScope.bind(worker)绑定,默认运行在RibDispatchers.Default,并支持通过context参数覆盖调度器。
可配置的错误处理:Rib.Configuration
libraries/rib-base/src/main/kotlin/com/uber/rib/core/Rib.kt 中的Rib对象提供全局配置入口:Rib.setConfiguration(configurationToSet)必须在任何 RIB 代码使用之前调用且只能调用一次,否则抛出IllegalStateException。配置项包括:
handleNonFatalError:非致命错误上报(默认实现直接抛异常导致崩溃);handleNonFatalWarning:非致命警告上报(默认静默);handleDebugMessage:调试日志输出(默认丢弃)。
Android 端安装与集成
根据 README 的 Installation 章节,Android 端推荐的最小集成方式是在build.gradle中加入:
dependencies { annotationProcessor 'com.uber.rib:rib-compiler-test:0.16.6' implementation 'com.uber.rib:rib-android:0.16.6' testImplementation 'com.uber.rib:rib-test:0.16.6' }三个坐标各司其职:
rib-compiler-test(注解处理器):处理@RibBuilder、@RibInteractor、@Initializer等注解(注解定义见 libraries/rib-base/src/main/kotlin/com/uber/rib/core/RibBuilder.kt、RibInteractor.kt、Initializer.kt),自动生成测试基类与 Dagger Scope(生成逻辑见 libraries/rib-compiler-test/src/main/kotlin/com/uber/rib/compiler/InteractorTestGenerator.kt);rib-android:Android 核心运行时库,提供RibActivity(RibActivity.kt)、ViewRouter、RibDebugOverlay、XRay等;rib-test:测试辅助库(FakeComponent、FakeInteractor、FakeRouter、FakeWorker等,见 libraries/rib-test/src/main/kotlin/com/uber/rib/core/)。
注意:示例中的
0.16.6是 README 撰写时的 Maven Central 发布版本,集成时建议以 Maven Central 实际最新版本为准,确保处理器与运行时库版本一致,避免注解处理与运行时 API 不匹配。
除了上述最小集,RIBs 还提供一系列扩展包,README 中特别提到:
- Kotlin 扩展:Kotlin 原生支持;
- Jetpack Compose 支持:见 libraries/rib-android-compose/,其中 BasicComposeRouter.kt 通过
MutableState<@Composable () -> Unit>槽位将ComposePresenter的 composable 挂入/移出组合; - Coroutines 支持:见 libraries/rib-coroutines/,提供
RibCoroutineScopes、RibDispatchers以及测试用的RibCoroutinesRule。
从仓库 settings.gradle 可以看出完整的模块体系还包括rib-base、rib-router-navigator(含StackRouterNavigator栈式导航,见 StackRouterNavigator.kt)、rib-workflow、rib-screen-stack-base、rib-coroutines-test、rib-debug-utils等库,以及tooling目录下的 IntelliJ 插件与 Flipper 插件。
围绕 RIBs 的工具链:让大型团队高效协作
README 将工具链列为 RIBs 的核心优势之一,仓库中对应实现包括:
- IntelliJ 插件(tooling/rib-intellij-plugin/):提供代码生成(快速创建 RIB 及其 Builder/Interactor/View 文件)、静态代码分析,以及运行时 RIB 结构可视化;
- Flipper 插件(tooling/rib-flipper-plugin/):将 RIB 树集成到 Facebook Flipper 调试器中,运行时直观查看 RIB 树与生命周期;
- 内存泄漏检测:通过
RibRefWatcher(见 libraries/rib-base/src/main/kotlin/com/uber/rib/core/RibRefWatcher.kt)在 Router 卸载时监视被删除对象,配合 LeakCanary 捕获泄漏;demos/memory-leaks/ 专门演示了这一场景; - 调试辅助:RouterDebugUtils.kt 提供
printRouterSubtree,以树形文本打印从任意 Router 出发的整棵 RIB 树;XRay.kt 可以在每个 RIB 视图背景上直接绘制 RIB 名称,便于肉眼核对界面与 RIB 的对应关系。
从教程到真实案例:仓库内的学习路径
README 提到官方提供了系列教程(Tutorials)帮助你动手掌握架构。在本仓库中对应:
- tutorials/tutorial1/:创建第一个 RIB,理解 Builder/Interactor/Router/View 的基础结构;
- tutorials/tutorial2/:多 RIB 与登录流程切换(LoggedOut / LoggedIn);
- tutorials/tutorial3/ 与 tutorial3-completed/:构建完整 Tic-Tac-Toe 游戏,涵盖子 RIB 挂载与状态管理;
- tutorials/tutorial4/:进阶用法(包含 Kotlin 文件,涉及更复杂的交互与导航)。
此外 demos/ 目录提供了可直接运行的真实示例:Compose 集成(demos/compose/)、Flipper 调试(demos/flipper/)、内存泄漏演示(demos/memory-leaks/)、协程 Worker 示例(demos/rib-workers/)与栈式导航(demos/stack-nav/)。克隆仓库后即可通过 Gradle 编译运行这些 Demo,作为理解 RIBs 的活教材。
许可证
RIBs 由 Uber Technologies 开发,2017 年开源,遵循Apache License 2.0(完整声明见 LICENSE.txt)。仓库 CHANGELOG.md 与 RELEASING.md 记录了版本演进与发布流程,供二次开发与版本升级参考。
- 移动开发
- 开发工具
【免费下载链接】RIBs
Uber's cross-platform mobile architecture framework - Android Repository
相关推荐
深入理解Uber RIBs:跨平台移动架构框架的终极指南
深入理解Uber RIBs:跨平台移动架构框架的终极指南 Uber RIBs是Uber开发的跨平台移动架构框架,专注于构建可扩展、可测试的移动应用。作为一款强大
移动开发开发工具RIBs Android 演进史:从 CHANGELOG 读懂 Uber 跨平台架构框架的关键版本变迁
RIBs Android 演进史:从 CHANGELOG 读懂 Uber 跨平台架构框架的关键版本变迁 本文以 RIBs 仓库根目录下的 CHANGELOG.m
移动开发开发工具如何快速掌握Uber RIBs:移动应用架构的终极指南
如何快速掌握Uber RIBs:移动应用架构的终极指南 Uber RIBs是Uber开源的跨平台移动架构框架,为大型团队开发复杂移动应用提供了完整的解决方案。R
移动开发开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考