Android UI 不必只在"传统 View"与"全量 Compose"之间二选一。
ViewCompose 提供了一条更务实的第三条路线:上层使用状态驱动的 Kotlin DSL 描述界面,底层仍然生成一棵真实的 Android View 树。
过去几年,Android UI 的讨论常被简化成一道二选一题:继续使用成熟但偏命令式的 View,或者迁移到 Jetpack Compose。
ViewCompose 希望提供第三种选择:开发者使用状态驱动的 Kotlin DSL 描述界面,框架负责组合、记忆、增量失效、差量协调和事务化提交,最终落地的仍然是一棵真实的 Android View 树。
这意味着,团队可以获得接近现代声明式 UI 的表达方式,同时继续利用 TextView、EditText、RecyclerView、ViewGroup、AndroidX 以及大量第三方 View 组件所积累的兼容性与工程经验。
它不是 Jetpack Compose 的兼容层,也不是对 Compose Compiler 的重写;它更像一套面向 View 生态重新设计的声明式框架。
一句话定位: ViewCompose 把"如何描述 UI"与"最终由什么渲染"拆开:上层是声明式、状态驱动和可组合的,底层仍由原生 Android View 执行。
一、它解决的不是语法问题,而是 View 项目的架构问题
如果只是把 new View、addView 和 setText 包成几层 Kotlin 函数,项目仍然要自行处理状态同步、局部刷新、身份复用、生命周期、保存恢复、异步副作用和失败回滚。
ViewCompose 的核心价值在于,它把这些横跨业务页面的共性问题收进了框架运行时:
- 状态读取会形成依赖,变化被合并并在帧边界触发更新;业务代码不再到处维护手工刷新链。
VNode与NodeSpec把组件语义变成不可变树,稳定 key、内容类型和结构身份可以参与协调与复用。- 渲染器根据差异执行创建、绑定、移动、回收与补丁,而不是每次重建整棵 View 树。
- 原生树更新具有准备、回滚、提交边界;不可逆工作被明确放到提交后的
onCommit。 - 状态、effect、saveable state、生命周期、ViewModel 和宿主 Session 都有清晰的所有权。
因此,ViewCompose 对原生 View 的提升不是"写法更像 Compose"这么简单,而是把散落在 Activity、Fragment、自定义 View、Adapter 和工具类里的 UI 基础设施,收敛成一个可测试、可复用、可诊断的统一模型。
二、五层架构:把能力做厚,把依赖做薄
项目把运行时模块划分为 Kernel、UI Foundation、Android Engine、Design System 与 Integrations 五层,并通过构建门禁阻止向上依赖、Material 渗入中立层、AndroidX 侵入纯 Kotlin 核心以及包归属漂移。
viewcompose-android 与 viewcompose-material3-android 是应用聚合入口,不被伪装成新的架构层;Preview 与 Benchmark 则保持为正交工具。

2.1 Kernel:把最难变化的规则做成纯 Kotlin
状态观察、文本编辑、UI 契约、导航事务、动画引擎、手势策略和图形模型尽量保持为纯 Kotlin/JVM。这样既降低 Android 平台耦合,也让规则可以在 JVM 单元测试中独立验证。
例如,TextFieldState 负责文本、选择区、输入法组合区、变换、撤销与重做;导航核心负责路由、回退栈和两阶段事务;渲染层只负责适配平台。
2.2 UI Foundation:公共 DSL 不绑定渲染器和设计系统
布局、组件、Theme/Defaults、UiLocal、组合协调、动画、手势与绘图 DSL 位于渲染器之上。它们描述"要什么",而不是直接操作某个 Android View。
Modifier 负责通用装饰与父布局数据,NodeSpec 负责组件语义,Theme/Defaults 负责默认值来源,三者各守边界,避免所有能力最终堆进一个万能参数袋。
2.3 Android Engine:把语义树可靠地变成原生 View
Renderer 负责节点工厂、绑定器、差量计划、容器复用、View 修饰符应用和补丁;Host 负责 renderInto、RenderSession、平台服务安装、帧调度、原生 View 互操作与最终释放。
二者不拥有 Material 策略,也不把业务 DSL 反向塞进平台层。
2.4 Design System 与 Integrations:按需组合,不让可选能力污染核心
Material 3、One UI 7、Overlay、Coil、Glide、Paging、CameraX、Maps、Media3、ConstraintLayout 等能力各自位于拥有它们的模块。
Material 是一等支持的设计系统,但不是框架地基;One UI 也不会在 Renderer 中增加一条按品牌判断的分支。设计策略先被解析为无品牌的颜色、几何、动效、语义和回退契约,再交给 Android Engine 执行。
架构亮点: 同一套运行时、状态模型、布局词汇、交互基础和渲染器,可以承载不同设计系统;真正不同的结构和组件语言仍由各设计系统自己拥有。
三、相比原生 View:把"状态同步"变成框架能力
3.1 从命令式更新,转向状态驱动
传统 View 页面往往同时存在 XML、findViewById/ViewBinding、Adapter、监听器、LiveData/Flow 收集和大量 updateXxx 方法。随着交互增加,"谁在什么时候更新哪个 View"会逐渐成为主要复杂度。
ViewCompose 让界面成为状态的函数:状态变化标记相关作用域,框架在帧边界合并失效并更新必要节点。
3.2 从手工增量刷新,转向统一的 diff / patch / reuse
原生开发者熟悉 RecyclerView 的 DiffUtil,但普通页面、嵌套容器、弹层和第三方 View 往往各有一套更新策略。
ViewCompose 把稳定身份、节点差异、局部补丁、回收重置和永久释放放进同一协调模型。Lazy 列表与 Pager 还拥有独立 Session 刷新路径,避免容器结构稳定时内容无法更新。
3.3 从"更新到一半出错",转向事务化原生树
复杂 UI 更新可能同时创建 View、移动节点、修改属性并绑定外部资源。ViewCompose 区分可重放的 update/reset、完整树成功后的 onCommit,以及永久放弃节点时的一次性 onRelease。
失败帧可以恢复已提交树,外部不可逆动作不会在半成品界面上提前发生。这种事务边界,是普通 View 页面很少系统化实现的能力。
3.4 继续拥有 View 生态,而不是与它割裂
最终节点仍是 TextView、EditText、RecyclerView、ViewGroup,或通过 AndroidViewAdapter 托管的第三方 View。
对于依赖输入法、无障碍、焦点、硬件按键、滚动嵌套、地图、相机、播放器以及 OEM 行为的应用,这条路径可以复用平台与既有组件的成熟实现,也更容易渐进嵌入现有 View 层级。
四、相比 Compose:底座不同,价值场景也不同
ViewCompose 借鉴了 remember、state、effect、Modifier、Lazy、Theme 等声明式概念,但它没有尝试伪装成 Compose。
两者在编译、布局、失效、互操作和宿主所有权上都有明确差异。对已经深度依赖 Compose 的新项目,这些差异未必是优势;对 View 资产庞大、需要渐进迁移或强依赖原生组件的团队,它们往往正是价值所在。
| 维度 | 传统原生 View | Jetpack Compose | ViewCompose |
|---|---|---|---|
| 开发模型 | 命令式为主 | 声明式 | 声明式 |
| 最终渲染树 | Android View | Compose UI 节点 | Android View |
| 编译依赖 | 无 Compose Compiler | 依赖 Compose Compiler 插件 | 不依赖 Compose Compiler |
| 布局权威 | MeasureSpec / LayoutParams | Compose Constraints | MeasureSpec / LayoutParams |
| 局部更新 | 通常由业务手工组织 | 编译器与 Runtime 协作 | 显式分组、状态观察与 diff/patch |
| 原生互操作 | 直接 | AndroidView 等桥接 | 原生树 + AndroidViewAdapter |
| 设计系统 | 由项目自行组合 | Material 生态成熟 | Material 可选、引擎中立、多设计系统 |
| 成熟度 | 平台级成熟 | 生态与工具链成熟 | Alpha,能力广但仍在收敛 |
这张表用于技术定位,不代表性能排名。
4.1 原生 View 树,是最直接的差异
Compose 通过自己的 UI 节点、测量、绘制与语义体系工作;ViewCompose 则把声明结果映射成原生 View。
后者对现有 View 主题、可访问性、输入法、窗口 Insets、焦点链、RecyclerView 复用和第三方控件更贴近原有工程边界。它也避免为了声明式写法引入 Compose 渲染引擎,但项目没有因此宣称整体性能、包体或启动速度必然优于 Compose。
4.2 不依赖 Compose Compiler,边界更显式
Compose 依靠编译器生成重启组、稳定性推断和跳过逻辑。ViewCompose 使用 ComposerLite、SlotTable、状态读取观察和显式节点组完成增量组合。
好处是框架不依赖 Compose 编译器插件,运行机制和更新边界更容易从源码追踪;代价是它没有 Compose 的自动稳定性推断与强跳过能力,开发者需要把状态读取放在足够小、足够稳定的组件边界。
4.3 View 测量规则仍是权威,迁移更真实也更克制
ViewCompose 的 Row、Column、Box 最终由原生 ViewGroup 测量和摆放,width、height、padding、margin 与 fill 解析到 LayoutParams 或容器规则。
它不会把 Compose 的 Measurable、Placeable 或自定义 Layout 原样搬过来。对于熟悉 View 的团队,这减少了"双重布局语义";对于依赖 Compose 自定义测量的页面,则必须改用内建容器、ConstraintLayout 或自定义 ViewGroup。
4.4 Modifier 不是 Modifier.Node 的复制品
ViewCompose 的 Modifier 是不可变值链,渲染器按属性族折叠并映射到原生 View。组件语义属于 NodeSpec,父布局数据属于 scoped Modifier,设计默认值属于 Theme/Defaults。
当前不支持应用自定义 Modifier.Node 生命周期。这种限制牺牲了 Compose 的一部分扩展自由,却换来更清楚的渲染边界和可预测的 View 复用。
4.5 设计系统不是引擎默认值
Compose 与 Material 的配套已经非常成熟;ViewCompose 的不同之处是从架构上禁止 Material 进入 Kernel、UI Foundation 与 Android Engine。
Material 3 是命名模块,One UI 7 也是独立模块,产品还可以构建自己的设计系统。Renderer 只接收已经解析好的中立契约,不知道这些颜色、形状或动效来自哪个品牌。
五、覆盖 38 个公开模块:从运行时到相机、地图与预览
截至本文资料基线,项目的公开模块目录登记了 38 个 Maven artifact,并为每个 artifact 配置独立模块手册。
它们不是一个"大而全"的单体依赖:标准应用可以从聚合模块进入,基础设施团队也可以只选择底层契约或某个集成。
Kernel · 7 个
纯 Kotlin 的状态、文本编辑、UI 契约、导航事务、动画、手势与图形策略。
viewcompose-runtime、viewcompose-text-core、viewcompose-ui-contract、viewcompose-navigation-core、viewcompose-animation-core、viewcompose-gesture-core、viewcompose-graphics-core
UI Foundation · 4 个
面向业务的声明式 UI、组件、环境、动效、手势和绘图 DSL。
viewcompose-ui-foundation、viewcompose-animation、viewcompose-gesture、viewcompose-graphics
Android Engine · 2 个
原生 View 协调渲染器与底层 RenderSession/Host。
viewcompose-renderer-android、viewcompose-host-android
Design System · 2 个
Material 3 动态色与主题桥接,以及独立的 One UI 7 Alpha 设计语言。
viewcompose-material3、viewcompose-oneui7
Integrations · 16 个
覆盖 AndroidX 生命周期与 ViewModel、导航、弹层、图片、阴影、ConstraintLayout、播放器、地图、相机和 Paging。
viewcompose-diagnostics、viewcompose-navigation-android、viewcompose-overlay-android、viewcompose-overlay-material3-android、viewcompose-overlay-oneui7-android、viewcompose-image-coil、viewcompose-image-glide、viewcompose-lifecycle-androidx、viewcompose-viewmodel-androidx、viewcompose-shadow-android、viewcompose-constraintlayout-androidx、viewcompose-media3-androidx、viewcompose-exoplayer2-android、viewcompose-google-maps-android、viewcompose-camerax-androidx、viewcompose-paging-androidx
Aggregates · 2 个
面向应用的一站式中立入口与 Material 3 入口,降低多模块选型成本。
viewcompose-android、viewcompose-material3-android
Preview Tooling · 5 个
预览协议、发现、隔离渲染、工作进程与截图回归;Benchmark 作为正交工程工具另行维护。
viewcompose-preview-core、viewcompose-preview-gradle-plugin、viewcompose-preview-runner、viewcompose-preview-worker-host、viewcompose-preview
六、文档与注释不是附属品,而是项目交付物
ViewCompose 很突出的竞争力,是把文档、注释、示例和质量门禁当成框架本身的一部分。
文档入口将架构、教程、指南、Compose 迁移、模块手册、工具、性能、路线图和发布流程分开管理;每个公开模块都有自己的手册,活动英文页面要求同步维护简体中文镜像。
- 公共/受保护 API 采用 Q0---Q3 质量等级;普通 API 至少达到契约完整的 Q2,高风险 API 要求 Q3。
- KDoc/Javadoc 不只解释名称,还要覆盖状态所有权、生命周期、并发、回调、失败、Android 行为、性能与兼容性等适用字段。
- Q3 API 必须引用可编译的
@sample;文档片段与样例源码之间有一致性校验,避免"文档能看、代码不能跑"。 - 所有公开模块进入严格 API 文档集合,Dokka 的
reportUndocumented与failOnWarning把缺失文档变成构建失败。 - 实现注释强调原因、约束、并发、回滚和平台 workaround,禁止逐行复述代码;TODO 需要可追踪事项和明确删除条件。
- 架构依赖、设计系统隔离、文档结构、翻译镜像、模块目录、迁移样例和发布变更均有自动校验。
对采用方的实际价值: 这套文档体系不仅方便第一次上手,也让团队能回答"这个 API 谁拥有、失败如何恢复、何时释放、版本变化影响哪个模块"等长期维护问题。
七、完整工具链,让声明式 View 不止停留在运行时
ViewCompose 同步建设了 Android Studio 静态预览、源码与渲染结果双向定位、亮暗主题与设备配置、VNode/Composition/Patch/Recomposition 诊断、隔离 Layoutlib Worker、截图回归和 Macrobenchmark。
诊断能力还能暴露渲染树、节点补丁时间线、UiLocal 快照、重组原因和可选的有界生产故障聚合。
尤其值得注意的是,开发工具被隔离在可选、可请求的路径上:应用运行时不依赖 Preview 和 Benchmark,未激活的诊断路径不能长期占用热路径。这与项目"能力可以做厚、默认依赖必须做薄"的整体思想一致。
八、它最适合哪些团队
- 拥有大量 XML、自定义 View、RecyclerView、播放器、地图、相机或厂商 SDK 资产,希望逐步声明式化的存量应用。
- 对 IME、焦点、无障碍、硬件输入、窗口与 OEM 行为敏感,不希望同时维护两套底层渲染模型的复杂应用。
- 需要 Material 之外的产品设计系统,或希望设计策略与渲染引擎严格隔离的平台团队。
- 重视源码可读性、模块独立发布、契约文档、可编译样例、架构门禁和故障诊断的基础设施团队。
如果团队正在开发完全没有 View 包袱的新应用,已经熟练使用 Compose,并高度依赖其成熟组件、第三方库、IDE 能力和社区经验,那么 Compose 仍然可能是更低风险的默认选择。
ViewCompose 的优势最明显地出现在"声明式生产力"和"原生 View 现实约束"同时存在的场景。
九、目前必须诚实面对的短板
9.1 仍处于 Alpha,API 与行为需要继续收敛
项目已经发布首个公共 Alpha,但 Alpha 就意味着公开 API 仍可能变化。独立模块版本能降低无关升级的影响,却也提高了版本组合和兼容管理的要求。
生产采用前,应围绕目标页面、目标设备和真实依赖做验证,而不是只看 Demo。
9.2 生态规模与人才供给无法和 Compose 相比
Compose 已经拥有官方资源、成熟组件、广泛第三方库、长期社区经验和完整 IDE 支持。
ViewCompose 虽然自建预览、诊断和迁移文档,但生态体量、真实项目样本、Stack Overflow 式知识沉淀和招聘可得性仍处于早期。框架团队需要承担更多支持与答疑责任。
9.3 Compose 能力不是一比一兼容
当前不支持通用 Compose 自定义 Layout、应用自定义 Modifier.Node、直接 AndroidViewBinding 或把 Fragment 放入渲染树。
UiLocal 的变化需要可观察状态驱动;任意 UI 子树 ViewModel Scope、部分 Insets 嵌套消费、某些派生状态/快照语义和自定义宿主恢复仍比 Compose 窄。迁移必须按语义重构,不能机械替换同名 API。
9.4 设备矩阵与视觉收敛仍有未完成项
路线图明确保留了真实设备上的中日文 IME、TalkBack、Switch Access、硬件键盘、多窗口、OEM 主题、Dark/Tablet 快照等验证任务。
One UI 7 仍是有限组件的 Alpha 集合;Material TextField 结构以及 Switch/Slider 几何和动效也保留了按产品需求启动的进一步收敛候选。
9.5 性能基础设施完整,但不应把"原生 View"直接等同于"更快"
项目已经建设 R8 Release、Macrobenchmark、Compose 对照、内存指标、diff/payload/SlotTable/子树跳过和阴影后端评估,但官方迁移文档明确不宣称与 Compose 性能等价。
当前更可靠的说法是:ViewCompose 有明确的性能模型与测量入口;是否更快、占用更低,仍必须在同设备、同构建模式、同工作负载下用数据回答。基线 Profile 的收益也仍待量化。
成熟度判断: ViewCompose 已经具备"完整框架"的横向宽度,但距离"默认无需评估即可用于所有生产项目"的成熟度仍有距离。它更适合愿意参与验证、能控制技术栈、并且确实需要 View 底座的团队。
结语:不是复制 Compose,而是重构 View 生态
ViewCompose 最值得宣传的地方,不是它拥有多少与 Compose 相似的函数名,而是它把声明式 UI 的核心方法------状态驱动、组合、增量更新、身份复用、结构化副作用与工具化诊断------重新建立在原生 Android View 之上。
它尊重 View 的测量、生命周期、输入与生态现实,又通过严格分层阻止平台细节、设计系统和可选集成反向污染核心。
对于长期维护 Android 大型应用的团队,这是一种很务实的技术选择:不否定已有资产,不要求一次性重写,却把未来页面的开发模型提升到声明式时代。
再加上 38 个公开模块、逐模块手册、严格 KDoc/Javadoc、可编译样例、Compose 迁移矩阵、预览、诊断和性能门禁,ViewCompose 展示的不只是一个 UI DSL,而是一套认真面向长期演进的开源工程。
项目主张: 保留原生 View 的确定性与兼容性,获得声明式 UI 的表达力与工程效率------这正是 ViewCompose 与 Compose 最根本、也最有价值的不同。
了解更多
说明:本文依据仓库中当前 README、架构规范、设计系统标准、模块目录、Compose 迁移矩阵、API 注释标准、性能文档与统一路线图整理。能力与状态会随独立模块版本演进,发布前建议复核最新公开文档。