Jetpack Compose前探

一、认识 Jetpack

在认识 Jetpack Compose之前,先来聊聊一个在名字上十分相似的工具集------Android Jetpack

Android 开发早期,官方并没有提供统一的架构规范。开发者们为了解决UI与业务逻辑耦合、生命周期管理、性能等问题,设计出了MVC、MVP、MVVM等架构模式,但这些终究是社区或个人的方案,权威性上还是不如官方。开发者不确定自己选择的架构是否真的是最佳方案。

直到2017年,Google推出了 Android Architecture Components (AAC),其中包含了ViewModelLiveDataRoom 等专为架构设计的组件。2018年,Google在AAC基础上进一步推出了全新的开发组件工具集------Android Jetpack 。它是一套库、工具和指南的集合,也是官方首次为Android 架构问题提供系统性的解决方案。

Android希望利用 Jetpack 来帮助开发者编写出更简洁、更一致的代码,减少样板代码,简化开发流程,让开发者可以将更多的精力放在业务代码上。

早期的 Jetpack 全家桶包括四大领域:Architecture(架构)、Foundation(基础)、Behavior(行为)和UI(界面)。下面的图正是官网早期架构图(2018年)。

细心的读者可能注意到,图中并没有我们今天要讨论的 Jetpack Compose。这是因为该图出自早期 Jetpack 宣传材料,Jetpack Compose是后面才发展出来的新技术。我们可以暂时将其理解为UI组件下的新一代成员,但实际上 Jetpack Compose 更应该是和 UI组件平行或独立分支------它不是对传统View系统的补充,而是彻底的替代,从布局、动画到交互,全面取代基于View的旧体系

二、认识 Jetpcak Compose

2019年的Google I/O大会上首次公布Android全新的UI开发框架------ Jetpack Compose(下面简称Compose)。同年10月发布首个Preview版本,2020年9月发布了第一个Alpha版本,2021年2月发布第一个Beta版本,最终在2021年7月推出了1.0正式版。

Compose是Android新一代的UI开发框架,其核心特征是采用声明式编程范式 。与传统的命令式方式不同,声明式UI的核心思想是:UI是状态的函数 ------UI = f(state),当状态变化时,UI自动重新绘制,无需开发者手动更新每个视图。

在2026年5月,Android更是正式官宣 Android UI开发进入"Compose优先"时代,传统的基于View + XML的UI工具包将进入维护模式,不再积极演进。这标志着Compose将成为Android UI开发的绝对主流方向,如同 Kotlin 代替 Java成为主流开发语言一样。

Compose具有的优势可以概括为:

  • 先进的开发范式,声明式编程范式大幅简化状态与UI的同步逻辑;
  • 更高的代码效率,用更少的代码实现了更丰富的界面;
  • 良好的兼容性,完整兼容传统View 体系;
  • 更方便的升级,Compose与操作系统解耦,无需等待操作系统升级才能解决BUG或升级功能;

三、为什么是 Compose

想要理解Android 为何官宣 "Compose优先",我们就需要知道旧方案------即基于View的命令式UI开发存在哪些弊端。

3.1 传统View开发的主要弊端

  • 繁琐的样板代码:findViewById、类型转换、setOnClickListener...,即使最简单的展示页面也需要类似大量重复代码;
  • 空指针风险:findViewById 返回可空类型,稍不注意就会引发NullPointerException
  • 命令式思维下,逻辑分散易出错:手写setter,需要手动找到对应的View,界面View多时容易遗漏,导致UI刷新异常;
  • XML解析的性能瓶颈:XML布局若层级深或包含很多View控件,通过反射或解析器生成View对象,影响性能;
  • 升级受限于操作系统:View必须跟随操作系统升级来解决问题或升级功能;
  • 开发效率低下:开发者频繁在XML文件和Java\Kotlin代码间之间切换,上下文割裂,可能打扰开发者思考;

3.2 为何痛点难以修复

传统View体系的这些痛点Google早已知道,但是积重难返------View体系的设计初衷就是面向静态界面

从2008年发布第一版系统,到现在Android已经发展了快20年,智能手机在这近20年无论是硬件还是软件都发生了巨大的变化。如今的APP早已不是简单的展示型界面。而是充满动态交互、多状态切换的复杂应用。当多个状态源(网络请求、用户输入、系统通知、本地缓存)同时变化时,传统View的命令式更新方式极易发生状态改变但UI未及时刷新的问题。与其继续在View.java这个超过1万行代码(不含注释等内容)、牵一发动全身的"巨无霸"类上不断打补丁,不如寻找一套新的UI开发方式。

四、Android UI 技术发展

可以简单将 Android UI 技术发展分为三个阶段:

4.1 原生View 体系(2008-2017)

这是Android 早期最经典的UI开发方式:使用 XML布局 + Java\Kotlin代码 的方式。通过XML的静态描述,运行时通过findViewById 来获取ViewId并通过setter方法修改属性。所有的View状态都需要代码显示调用。

java 复制代码
Button button = findViewById(R.id.button);
TextView content = findViewById(R.id.tv_content);
button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
				content.setText("Hello World");                
            }
        });

随着应用的复杂度提升代码复杂度也愈发明显。

4.2 架构感知过渡阶段(2017-2021)

这个时期,Google推出了Android Architecture Components (AAC),数据驱动UI 的思想开始萌芽。LiveDataViewModel 等组件帮助开发者更好的管理状态和生命周期。同时,ViewBindingDataBinding替代了findViewById的模板代码,并支持双向绑定。我们可以在XML布局里直接感知数据变化。代码示例:

kotlin 复制代码
// 使用 ViewBinding
val binding = ActivityMainBinding.inflate(layoutInflater)
binding.tvContent.text = "Hello"
// 配合 LiveData
viewModel.userName.observe(this) { name ->
    binding.tvContent.text = name
}

这个阶段虽然改善了代码结构,但本质还是命令式更新逻辑,状态与UI的同步还是需要手动触发。

4.3 声明式Compose时代(2021-至今)

Compose 彻底抛弃了XML + View的模式,使用组合函数 (@composable)来描述UI。UI不再是静态模板,而是一个可组合的函数调用树,状态有变化会自动触发重组(Recomposition),且只更新变化的部分。

kotlin 复制代码
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    Text(
        text = "Hello $name!",
        modifier = modifier
    )
}

配合stateremember,状态管理简洁又安全。

kotlin 复制代码
@Composable
fun Counter() {
    var count by remember { mutableStateOf(0) }
    Button(onClick = { count++ }) {
        Text("Clicked $count times")
    }
}

五、后记

本篇作为 Jetpack Compose 系列文章的开篇,简单梳理了Jetpack背景、Compose的诞生历程、传统View的弊端以及Android UI技术演进之路。后续会继续更新 Jetpack Compose 相关的更多内容,比如Compose组件使用、状态管理、重组、动画等等,欢迎持续关注。

如果在阅读过程中有任何疑问或想法,也十分欢迎在评论区留言交流。

六、参考资料