小鱼在桔厂-- Conductor

入职新公司第三天,处于学习App架构阶段,这边的客户端开发架构依赖于自研的Nova Skeleton框架,而该框架的底层实现是基于Conductor框架,我们就先来看看Conductor是个啥。
Conductor按照官方说法就是一个小而全功能的框架,允许构建基于视图的 Android 应用程序。

Conductor特点

Conductor原理简单介绍

Conductor的基本原理就是Activity充当一个容器,布局文件里定义一个ViewGroup当做Container,把这个Container传给Conductor框架,然后所有的UI逻辑实际上就是Conductor在操作这个Container里面的View。


Conductor视图原理

容器化

按照我的理解就是,Conductor就是在Android开发中不依赖于系统本身提供的UI开发套件,而是直接把单一的Activity当成框架的容器来用,基于此容器,上层的UI显示,生命周期管理,传值回调等由自己本身来实现。

看到这块是不是感觉很熟悉,没错,我们来回顾一下客户端跨端技术的演变过程。


跨端技术演进

Hybird实际就是Android的Activity当成WebView容器,内部UI由WebVeiw来完成。

ReactNative实际上也是Android Activity提供一个容器,内部UI由ReactRootVeiw完成。

Flutter的话则更极端一点,Flutter是自渲染的,UI渲染由自己的Skia引擎去完成,但是Flutter引擎也需要一个Android Activity作为承载容器。

所以从思路上来说Conductor和上面这几种跨端技术有一定的相似性。

那么就引出一个思考,为啥Conductor框架放着好好的AndroidUI套件不用,要自实现一套呢?按我的理解是为了模糊View和Page的界限,为了做彻底的组件化做准备。

组件化

首先组件这个词的意思就是可组装的配件,那都可组装了,它最大的特点就出炉了,就是为了复用。要说组件我们要先说页面。

我们先用传统的Android App来说一下,一个完整的App是由多个页面组成的。页面,指的是充满整个屏幕的视图容器。常见的页面包括登录页、首页、个人页等等。Android里页面特指Activity和Fragment。那页面里面的元素,比如登录页面的登录Button,在Android里那就是一个View。

一切皆组件的框架比如React,Vue,Flutter,这些框架就是模糊了页面和View的概念,统一把他用组件来表示,在UI维度组件既可以是一个View,也可以是一个页面,在业务维度,组件就是封装出具备特定业务功能的UI元素组合。

可能初看起来比较奇怪,无非就是换了个概念而已。但是从底层框架实现角度而言,一个概念后面就有一套框架支撑。将两个概念合并,使得整个框架更加简单、清晰。 ----MaxieeWang

Conductor框架实际上就是在Android里一切皆组件的框架,在这个点上,它和React,Vue,Flutter是一致的。

Conductor核心类

Controller 控制器

Controller 是 Fragment 的替代品, 可以把它理解成 Conductor 中的 Fragment.
它是对视图 View 的封装, 并提供生命周期感知功能.
Controller 的实现比 Fragment 的实现要轻, 状态比 Fragment 更加可控, 生命周期更易于打理

Router 路由

Router 负责 Controller 的切换 (在 Conductor 中, Controller 的切换就是切页面)
Router 内部实现了一个返回栈, 用于保存 Controller 事务切换历史
根Router 需要绑定在一个 Activity 和 Activity 提供的一个 ViewGroup container 上面. 其中, ViewGroup container 就是 Controller 界面到时候显示的地方
有一点要注意的是:
Conductor 的 Router 并不直接负责页面切换, 它把切换页面的职责代理了出去
代理给一簇专门的类 ControllerChangeHandler 之所以要加这一层代理, 是因为这样就实现了对酷炫的过场动效的支持, 这一能力支持是 Conductor 比较突出的特性之一

ControllerChangeHandler

前面说 Router 把切换页面的职责代理了出去, 就是代理给了 ControllerChangeHandler
ControllerChangeHandler 的职责是将老的 Controller 的视图切出, 把新的 Controller 的视图切入, 并实现切换时的动画效果
有了 ControllerChangeHandler, 过长动画变得很容易实现. Conductor 框架内置了多种带动效的 ControllerChangeHandler
ControllerChangeHandler 是业务无关的, 在切 Controller 时 new 一个具体的 ControllerChangeHandler 就实现了过场动效

ControllerTransaction

ControllerTransaction 是用于 Router 内部的一个数据接口.
每次我们切页面, 就会创建一个 ControllerTransaction 保存这次切面面相关的上下文 (from controller, to controller, container ViewGroup, applied ControllerChagneHandler)
Router 内部维护了一个 ControllerTransaction 的 list, 刚创建的这个 ControllerTransaction 会入队
Router 会根据这个队列来执行切换操作
也就是说 Router 维护了一个队列来切面, 这样的目的是为了保证切页面的状态是可控的


image.png

image.png

总结

每个框架的产生都有它的理由,在2016年那个时间点Conductor框架的诞生我想也是为了解决当时Android开发的一些问题(Fragment难用,组件化困难等)。之后的Uber ribs架构也借鉴了Conductor的一些思想,我们团队的客户端整体架构,底层也是引入的Conductor。目前来说Android的技术生态也在Google的带领下不断的规范化,Jetpack Compose这种全新的Android UI开发方式甚至也能看到Conductor的影子,从这些方面来看,Conductor无疑是成功的。

你可能感兴趣的:(小鱼在桔厂-- Conductor)