本文首发于公众号:OpenFlutter
前几天,Google 在 Android 官方开发者文档上更新了一篇看起来不起眼、但实际上分量极重的页面------《Android is Compose-first》。
一句话总结:View 工具包,正式进入维护模式。
刚看到这个文章时,我不免感慨:时代的车轮真是滚滚向前......我从20年开始使用Jetpack Compose,从一开始我就特别喜欢Compose,尽管在这其中经历了许许多多的API变更,但不影响Compose是趋势的事实,在2021年的时候,我就在公司内部极力推广过Compose,鼓励大家学习Compose,但是当看到这个文章时,我仍然还是有点震惊,因为这天感觉来的太快了。所以,那些还在维护View 体系的兄弟姐妹们应该明白一件事:
Google 不打算再管Android View系统了。
可以说这不是"以后会逐步淘汰",不是"建议大家考虑迁移",是直接盖棺定论:
"We now consider the View toolkit to be in maintenance mode --- this means that it will only receive highly critical fixes."
"highly critical fixes"------翻译成人话就是:除非崩到影响 Google 自家收入,否则别指望有人修。新 API 不会有,新组件不会有,新文档不会有,新工具更不会有。
android.widget 整个包从今天起就是一具被防腐处理过的标本。它还能用,但它已经死了。
当然了,
android.view包本身会保留,因为 Compose 自己也要靠它当底层管道。但作为一个"UI 框架",View 时代到此结束。
一、一份 21 个名字的被遗弃名单
不仅是android.widget中的类,如TextView和ListView已经进入了维护模式,基于 View 的Jetpack库也未难幸免于难。下面是Google 在原文里直接列出了进入维护模式的 View 体系 Jetpack 库。我数了一下,21 个。这哪是淘汰几个边角料,简直就是把整条技术栈端走:
scss
CardView ConstraintLayout CoordinatorLayout
CustomView DataBinding DragAndDrop
DrawerLayout DynamicAnimation Emoji
Fragment GridLayout Interpolator
Loader Navigation PercentLayout
Preference RecyclerView SlidingPaneLayout
SwipeRefreshLayout Transition VectorDrawable
ViewPager ViewPager2
Material Design Components (Views)
逐个念一遍这份名单,等于把过去十年的 Android 技术博客全部读了一遍。
Fragment 进了。 那个被 Square 工程师在 2014 年写过一篇神文骂"应该从 Android 里删除"的 Fragment,那个 FragmentManager + FragmentTransaction + commitAllowingStateLoss 让无数人调试到凌晨三点的 Fragment------它终于熬到了维护模式。从 2011 年 Honeycomb 引入算起,活了 15 年。
RecyclerView 进了。 当年我们多么欢迎它替代 ListView:ViewHolder 强制模式、ItemDecoration 解耦绘制、DiffUtil 增量更新、ItemAnimator 动画解耦------一套漂亮的设计。然后呢?LazyColumn 一个 items {} 就把它全部干掉了:
kotlin
// View 时代:
class MyAdapter(private val data: List<Item>)
: RecyclerView.Adapter<MyAdapter.VH>() {
class VH(view: View) : RecyclerView.ViewHolder(view) {
val title: TextView = view.findViewById(R.id.title)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item, parent, false)
return VH(view)
}
override fun onBindViewHolder(holder: VH, position: Int) {
holder.title.text = data[position].title
}
override fun getItemCount() = data.size
}
// 加上 XML 布局、加上 RecyclerView 配置、加上 LayoutManager 设置......
// Compose 时代:
LazyColumn {
items(data) { item ->
Text(item.title)
}
}
四行 vs 二十几行外加一个 XML 文件。这就是结论。
ConstraintLayout 进了。 这个堪称 View 时代最后一次重大设计创新的库,引入了链式约束、屏障、引导线、流式布局,号称要"消灭嵌套地狱"。它做到了。然后 Compose 出来,连"嵌套"这个概念本身都不存在了------一切都是函数调用,性能跟扁平布局没有区别。
DataBinding 进了。 那个引入了 <layout> 标签、<variable> 声明、@{...} 表达式、强制 KAPT 注解处理、编译期生成 ActivityMainBinding 的库。在Compose之前我可以说是非常忠爱这个库了,虽然它可以解决 findViewById 的样板代码问题,但结果引入了更难调试的编译期错误和拖累构建速度的 KAPT。现在好了,Compose 里根本没有"View 引用"这个概念,直接告别。
Navigation(View 版本)进了。 留下的是 Navigation Compose------一个 API 更简洁、类型更安全(结合 Kotlin Serialization)、对深链处理更优雅的替代品。
Material Design Components for Android(MDC-Android)进了。 Material 团队这些年明显把所有热情都倒进了 Compose Material 3。Views 版本的 MDC 早就在吃老本。
我特别想点名的是 CardView。这个 2014 年随 Lollipop 一起出现的小库,提供了一个简单的需求:"请给我一个有圆角和阴影的容器"。这个需求当年要写多少代码?要在 5.0 以下做多少 fallback?而在 Compose 里:
kotlin
Card(
elevation = CardDefaults.cardElevation(4.dp),
shape = RoundedCornerShape(12.dp)
) {
// 内容
}
CardView 这种"用一个完整的 Jetpack 库去实现一个视觉效果"的存在方式本身,就是 View 体系僵化的一个缩影:什么新需求都得"出一个库"。
二、工具链也被切了一刀
如果说 View 库进入维护模式是预料之中,那 Google 对工具链的处理则相当不留情面:
"Any new Android Studio UI tools will be built for Jetpack Compose only."
新的 Android Studio UI 工具,只会为 Compose 而造。
这句话意味着:
- Layout Editor(那个可视化拖 XML 的界面)------维护模式
- Navigation Editor(那个画导航图的界面)------维护模式
- 未来 Android Studio 推出的所有 UI 相关新功能(包括 AI 辅助设计、新的预览系统、新的调试工具),只服务于 Compose
文档层面更直接:所有 Codelab、Sample、Training,全面 Compose-first。View 相关的内容只会"在相关页面作为链接保留"------也就是塞进角落。
简单粗暴地说:未来的 Android 开发者,搜索 Android UI tutorial 第一页结果里将不再有 XML。
三、Compose 凭什么赢
平心而论,Compose 赢得这场胜利,技术上是有底气的。
1. 模型上彻底解决了"UI 与状态同步"这个根本问题。
View 体系是命令式的:状态在 ViewModel 里,UI 在 View 树里,中间靠你手动同步。同步漏了一处,UI 就错了。MVP、MVVM、DataBinding、LiveData------这十年所有架构模式的演进,本质上都是在打补丁。
Compose 是声明式的:你描述"UI 在某个状态下应该长什么样",框架自己负责把 UI 同步到那个状态。同步漏了?没这个概念,因为根本不存在"同步"这个动作。
2. Recomposition 模型在性能上跑得过 View。
很多人最初担心 Compose 慢------每次状态变化都重新执行一遍函数,听起来就慢。但 Compose 编译器做了大量工作:通过 @Stable、@Immutable 注解和强跳过(Strong Skipping)模式,只有真正受影响的 composable 才会重组。配合 Baseline Profiles,冷启动性能甚至比同等 View 实现更好。
3. 跨形态写一套搞定。
这才是 Google 真正的算盘。Wear OS Compose、Compose for TV、Compose for XR、Glance(用于 Widget)......Google 在所有新形态上的 UI 框架统统是 Compose 的方言。一套 Composable 通过 Window Size Classes 适配手机/平板/折叠屏,再通过形态特化适配手表/电视/眼镜。
View 体系做这件事?根本无解。
4. Kotlin DSL 把表达力拉满。
Modifier 链式调用、trailing lambda 作为 slot、remember { } 配合 MutableState 的状态管理------这些都是 Java 时代的 Android UI 框架想都不敢想的东西。Compose 是第一个"为 Kotlin 而生"的 Android UI 框架,它的 API 设计完全围绕 Kotlin 的语言特性展开。
四、迁移策略:现在该怎么办
Google 留了 interop API 作为缓冲。但"留下缓冲"和"可以摆烂"是两回事。
短期(即刻):
- 新模块、新页面、新组件------全部 Compose,没有例外。这不是技术选型问题,这是基本职业素养问题。继续写 XML 等于主动给自己未来的简历减分。
- 现有项目接入 Compose------通过
ComposeView嵌入到现有 Activity/Fragment 里,从最不依赖外部状态的页面开始(比如设置页、关于页、空状态页)。
中期(一年内):
- 用
LazyColumn替换RecyclerView------这是收益最高的迁移,代码量直接砍掉一半以上。 - 用 Navigation Compose 替换 Jetpack Navigation------尤其结合 Kotlin Serialization 的类型安全路由,体验差距非常明显。
- 用 Compose Material 3 替换 MDC------主题系统更清晰,组件 API 更现代。
长期(持续):
- 啃硬骨头:自定义 View 的迁移。这部分最痛苦,因为很多自定义 View 用了大量
Canvas直接绘制、onMeasure自定义测量。好消息是 Compose 的Canvas和LayoutAPI 完全能覆盖这些场景,只是要重写思维。 - Fragment 的彻底告别。这意味着要重新设计页面级状态管理------通常用 Navigation Compose + ViewModel 就够了。
- DataBinding 的拆除------这部分相对简单,因为 Compose 本身就把数据绑定问题解决了。
根本回避不了的现实:超大型项目(百万行代码级别)的完整迁移可能要花数年。但 Google 既然画了红线,路线图就摆在那里,迁移不是要不要的问题,是早做还是晚做的问题。
五、写在最后
平心而论,View 体系是了不起的。
它从 2008 年 Android 1.0 走到 2026 年,整整 18 年。它支撑了人类历史上最大规模的移动应用生态。Activity + Fragment + XML + findViewById 这一套,是几百万开发者的肌肉记忆。
但它确实是上个时代的产物:诞生在 Java 6 的语言能力下,诞生在屏幕只有一种尺寸的时代,诞生在响应式编程还没有成为主流的年代。它扛了太多它本来没设计去扛的东西------Material Design、动态主题、折叠屏、多窗口、动画系统------每一次扩展都让架构更别扭一点。
到了 Compose 出来的 2019 年,Android UI 框架的债已经还不动了。Google 选择推倒重来,是个艰难但正确的决定。今天的 Compose-first 公告,只是把这个早就发生的事实写在了纸面上而已。
所以------
findViewById,再见。<LinearLayout android:orientation="vertical">,再见。onCreateView里那段inflater.inflate(R.layout.fragment_xxx, container, false),再见。RecyclerView.Adapter<MyVH>,再见。commitAllowingStateLoss,特别再见。
"The Views system is now in maintenance mode."
一句话,一个时代。
各位还在 XML 里挣扎的朋友:醒醒。Google 已经把灯关了。
------ Happy Composing.