从 ComponentActivity 看 Android Activity 的演变与 Jetpack 架构融合

在 Jetpack Compose 出现后,开发者可能会注意到一个变化:项目的主 Activity 默认从过去熟悉的 AppCompatActivity 变成了 ComponentActivity。这个变化并非偶然,而是 Android 架构在向现代组件化演进过程中一个关键的转折点。本文将围绕 ComponentActivity,深入讲解它的来历、意义以及它在 Jetpack 架构中的作用。


一、Activity 的演变简史

Android 应用的生命周期核心组件是 Activity。随着 Android 框架的发展,Activity 的实现也经历了多个阶段的演进:

  1. 最初版本:Activity

    • 提供基本的生命周期管理、UI 渲染能力。
    • 但没有支持架构组件(如 ViewModel、LiveData、Lifecycle)的能力。
  2. 引入 Fragment 的 FragmentActivity

    • 为支持 Fragment 的使用,Google 引入了 android.support.v4.app.FragmentActivity
    • 后来演变为 AndroidX 中的 androidx.fragment.app.FragmentActivity
  3. 加入兼容特性的 AppCompatActivity

    • 为支持向下兼容的主题、控件、ActionBar 等特性,AppCompatActivity 出现。
    • 是多数 XML 时代 UI 项目的默认基类。
  4. 四个类的简介及继承关系

    • Activity
      Android 框架最原始的 Activity,提供最基本的组件生命周期管理,是所有 Activity 的基类。传统上开发者直接继承它来开发应用,但它的功能比较基础,没有内置对现代架构组件(如 Lifecycle、ViewModel 等)的支持。

    • ComponentActivity
      引入较晚,作为一种扩展版的 Activity。它继承自 Activity,并内置了对 Android Architecture Components 的支持(例如 LifecycleOwner、SavedStateRegistryOwner 等)。ComponentActivity 专注于解耦业务逻辑和 UI 之间的关系,能更好地支持新一代的应用架构,也为 Compose 提供了简洁的入口。

    • FragmentActivity
      继承自 Activity 的一个扩展类,主要目的是为 Activity 提供对 Fragment 的支持。FragmentActivity 随着 Android 支持库的出现而推出,目的是让旧版本的 Android 也能使用 Fragment 相关功能。

    • AppCompatActivity
      是 FragmentActivity 的子类,属于 AndroidX AppCompat 库。它为应用提供了最新的 Material Design 组件和向下兼容的特性,例如支持 ActionBar、菜单主题和其他 UI 组件。很多旧项目基于 AppCompatActivity 来保持对老系统的兼容性,同时获得新 UI 组件支持。


二、为什么中途引入 ComponentActivity?

Jetpack 架构组件(如 ViewModel、Lifecycle、SavedState 等)最早在 2017 年推出,最初使用一些工具类(如 ViewModelProviders)在 Activity 中进行适配。但随着 Jetpack 架构体系逐渐成熟,Google 逐渐意识到:

需要一个统一、轻量、无 UI 依赖的 Activity 基类,来天然支持 Jetpack 架构组件。

ComponentActivity 来自于 AndroidX Activity 库,首次引入是在:

androidx.activity:activity:1.0.0
📅 发布于 2019年6月(在 Google I/O 2019 前后)

  • 官方文档链接:https://developer.android.com/jetpack/androidx/releases/activity
  • 它是 Jetpack 架构组件整合的一部分,起初目的是为支持 ViewModel、Lifecycle 等架构的注入。

早期的结构大致是这样的:

AppCompatActivity↳ FragmentActivity↳ Activity

而引入 ComponentActivity 后,变成了:

AppCompatActivity↳ FragmentActivity↳ ComponentActivity  ← 新插入↳ Activity

ComponentActivity 实现了多个接口,使得其具备以下能力:

  • 是一个 LifecycleOwner
  • 是一个 ViewModelStoreOwner
  • 是一个 SavedStateRegistryOwner
  • 是一个 OnBackPressedDispatcherOwner

这使得 Activity 不再需要借助辅助类,就可以天然使用 ViewModel、SavedState 等功能。


三、为什么 Compose 默认使用 ComponentActivity?

Compose 推出的目标是简化 UI 构建流程,同时完全脱离传统的 XML、Fragment 体系。

3.1 轻量化与现代架构支持

  • Compose 的轻量化思想
    Compose 是一种声明式 UI 框架,它本身能够大幅简化 UI 的构建过程,不再需要通过 XML 和繁琐的视图树管理。如果项目全部采用 Compose 开发,许多传统由 Fragment 提供的“UI 组件化”方案就不再必需。

  • ComponentActivity 的优势
    ComponentActivity 内置了对 Lifecycle、SavedStateRegistry 等现代架构组件的支持,这与 Compose 的声明式和状态驱动模式更契合。相比之下,AppCompatActivity 通常承载了历史遗留的兼容层,如果应用全用 Compose,这层兼容性反而成了额外的负担。

3.2 模板和标准化演进

  • 官方模板的变更
    以前的项目模板往往基于 AppCompatActivity,是因为当时大部分项目都需要兼容 Fragment 以及一些传统 UI 需求。随着 Compose 的推广,Google 推出了更精简的模板,默认选择 ComponentActivity,从而鼓励使用新架构和纯 Compose 代码。

  • 降低复杂度
    对于纯 Compose 应用,ComponentActivity 已经足够支撑诸如导航、状态保存等需求,不需要额外依赖 AppCompat 的兼容层,简化了依赖结构,也能减少应用体积。

  • 一个 足够轻量 的 Activity,避免 UI 控件和兼容库的冗余依赖。

  • 一个 完美兼容 Jetpack 架构组件 的容器。

于是,Compose 的推荐写法变成了:

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {MyComposeApp()}}
}

这正是 Compose 使用 ComponentActivity 的原因:

它足够干净、足够现代,同时提供了 Compose 和 Jetpack 架构无缝连接的能力。


四、ComponentActivity 如何促进 ViewModel 使用方式演进?

既然 ViewModel 和 LiveData 更早就有,那为什么 ComponentActivity 要到 2019 年才引入来支持它们?

下面我详细解释一下时间线和背景👇


🕰️ ViewModel 和 LiveData 的引入时间

  • LiveData

    • 首次引入版本:android.arch.lifecycle:runtime:1.0.0
    • 发布时间:2017年11月(Google I/O 2017 之后)
  • ViewModel

    • 同样首次出现在 android.arch.lifecycle:viewmodel:1.0.0
    • 发布时间也是:2017年11月

📦 它们当时是属于 android.arch.* 包名下,也就是 Jetpack 的 早期版本(现在都迁移到了 androidx.* 包中)。


🤔 那为什么 ComponentActivity 要到 2019 年才出现?

原因是这样的:

✅ 1. 最初是通过 ViewModelHelpers 适配的

在 ViewModel 刚发布的时候,为了让开发者在不同类型的 Activity/Fragment 中用 ViewModel,Google 提供了“Helper 类”来协助获取:

ViewModelProviders.of(activity).get(MyViewModel::class.java)

这其实是通过“工具方法”来适配 FragmentActivityAppCompatActivity,不是通过统一的基类来支持架构组件。


✅ 2. 后来 Google 想系统性地整合架构组件支持

为了彻底解耦各种 Activity 的生命周期管理、状态保存、ViewModel 等支持,Google 决定:

抽出一个专门的基类 ComponentActivity,来做为现代架构组件支持的通用基础。

这个类整合了:

  • LifecycleOwner
  • ViewModelStoreOwner
  • SavedStateRegistryOwner
  • OnBackPressedDispatcherOwner(也支持 Compose 的 back handling)

它让所有 Activity 都可以天然具备使用架构组件的能力,不再依赖工具类或中间层。

  • 你现在在 Compose 项目中可以直接这样写:
class MainActivity : ComponentActivity() {val viewModel by viewModels<MyViewModel>()...
}

这是 ComponentActivity 实现了 ViewModelStoreOwner 才能这么用,旧的 Activity 是不行的。

不但代码更简洁,而且可以更方便地与 SavedStateHandleActivityResultLifecycleObserver 等 Jetpack 能力结合。

从此,ViewModel 与 Activity 的结合方式更加清晰、现代、类型安全。


五、小结

ActivityFragmentActivityAppCompatActivity 的历史路径中,我们可以看出 Android 为适应不断变化的 UI 架构做出的调整。而 ComponentActivity 的加入,是 Jetpack 架构化进程中的一次重要升级:

  • 它为 ViewModel、Lifecycle、SavedState 提供了统一支持
  • 它是 Compose 的天然基座
  • 它让现代开发变得更简单、更一致

可以说,没有 ComponentActivity,就没有 Compose 时代 Jetpack 架构的统一闭环。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/77319.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 防火墙( iptables )

目录 一、 Linux 防火墙基础 1. 防火墙基础概念 &#xff08;1&#xff09;防火墙的概述与作用 &#xff08;2&#xff09;防火墙的结构与匹配流程 &#xff08;3&#xff09;防火墙的类别与各个防火墙的区别 2. iptables 的表、链结构 &#xff08;1&#xff09;规则表 …

大数据 - 2. Hadoop - HDFS(分布式文件系统)

前言 为什么海量数据需要分布式存储技术&#xff1f; 文件过大时&#xff0c;单台服务器无法承担&#xff0c;要靠数量来解决。数量的提升带来的是网络传输、磁盘读写、CPU、内存等各方面的提升。 众多的服务器一起工作&#xff0c;如何保证高效且不出错 &#xff1f; 大数…

使用cursor进行原型图设计

1.下载cursor 2.模式设置&#xff1a; 模型使用claude-3.7-sonnet的think模式 3.引导词模板&#xff1a; 我想要开发一个中高考英语口语考试的模拟考试系统&#xff0c;我需要将上面的这个应用输出成高保真的原型图设计。请考虑以下的规范&#xff1a; 用户体验&#xff1…

极狐GitLab 功能标志详解

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 功能标志 (BASIC ALL) 使用功能标志&#xff0c;您可以将应用程序的新功能小批量部署到生产环境中。您可以为部分用户打开和…

AI与无人驾驶汽车:如何通过机器学习提升自动驾驶系统的安全性?

引言 想象一下&#xff0c;在高速公路上&#xff0c;一辆无人驾驶汽车正平稳行驶。突然&#xff0c;前方的车辆紧急刹车&#xff0c;而旁边车道有一辆摩托车正快速接近。在这千钧一发的瞬间&#xff0c;自动驾驶系统迅速分析路况&#xff0c;判断最安全的避险方案&#xff0c;精…

【NLP 63、大模型应用 —— Agent】

人与人最大的差距就是勇气和执行力&#xff0c;也是唯一的差距 —— 25.4.16 一、Agent 相关工作 二、Agent 特点 核心特征&#xff1a; 1.专有场景&#xff08;针对某个垂直领域&#xff09; 2.保留记忆&#xff08;以一个特定顺序做一些特定任务&#xff0c;记忆当前任务的前…

RAGFlow本地部署教程 :多模态检索+动态生成,用AI重构企业知识生产力

RAGFlow是一款基于检索增强生成&#xff08;RAG&#xff09;技术的智能工作流平台&#xff0c;通过整合多源数据检索与生成式AI模型&#xff0c;优化企业知识管理、智能问答及自动化报告生成&#xff0c;核心功能包括&#xff1a; 多源数据融合&#xff1a;支持数据库、文档库、…

【C/C++】深入理解指针(二)

文章目录 深入理解指针(二)1.const修饰指针1.1 const修饰变量1.2 const修饰指针变量 2.野指针2.1 野指针成因1.指针未初始化2. 指针越界访问3.指针指向的空间释放 2.2 如何规避野指针2.2.1 指针初始化2.2.2 小心指针越界2.2.3 指针变量不再使⽤时&#xff0c;及时置NULL&#x…

【verilog】在同一个 always 块中写了多个“看起来独立”的 if / if-else,到底谁先谁后,怎么执行?会不会冲突?

&#x1f50d; 问题本质 在一个 always (posedge clk) 块中&#xff0c;所有的代码都是顺序执行的。但这不意味着它就像软件一样“一条一条执行”&#xff0c;因为最终是电路&#xff01;电路是并行存在的&#xff01; Verilog 是硬件描述语言&#xff08;HDL&#xff09;&am…

【React】什么是 Hook

useStateuseEffectuseRef 什么是hook&#xff1f;16.8版本出现的新特性。可以在不编写class组件的情况下使用state以及其它的React特性 为什么有hook&#xff1f;class组件很难提取公共的重用的代码&#xff0c;然后反复使用&#xff1b;不编写类组件也可以使用类组件的状态st…

如何查看自己抖音的IP属地?详细教程及如何修改

在当今互联网时代&#xff0c;IP属地信息已成为各大社交平台&#xff08;如抖音、微博、快手等&#xff09;展示用户真实网络位置的重要功能。以下是关于如何查看抖音IP属地的详细教程及常见问题解答&#xff0c;帮助您快速了解相关信息&#xff1a; 一、如何查看抖音账号的IP属…

深度学习算力革新:AI服务器在运维工作中的智能化实践

【导语】作为IT基础设施服务领域的从业者&#xff0c;我们在日常工作中发现&#xff0c;AI服务器的智能化运维能力正在重塑传统IDC的管理模式。本文将以DeepSeek系列服务器为例&#xff0c;分享智能算力设备在真实运维场景中的创新应用。 一、传统服务器集群的运维痛点 在数据…

安装部署RabbitMQ

一、RabbitMQ安装部署 1、下载epel源 2、安装RabbitMQ 3、启动RabbitMQ web管理界面 启用插件 rabbitmq数据目录 创建rabbitmq用户 设置为管理员角色 给用户赋予权限 4、访问rabbitmq

中间件--ClickHouse-4--向量化执行(什么是向量?为什么向量化执行的更快?)

1、向量&#xff08;Vector&#xff09;的概念 &#xff08;1&#xff09;、向量的定义 向量&#xff1a;在计算机科学中&#xff0c;向量是一组同类型数据的有序集合&#xff0c;例如一个包含多个数值的数组。在数据库中&#xff0c;向量通常指批量数据&#xff08;如一列数…

Python PDF 转 Markdown 工具库对比与推荐

根据最新评测及开源社区实践&#xff0c;以下为综合性能与适用场景的推荐方案&#xff1a; 1. ‌Marker‌ ‌特点‌&#xff1a; 转换速度快&#xff0c;支持表格、公式&#xff08;转为 LaTeX&#xff09;、图片提取&#xff0c;适配复杂排版文档‌。依赖 PyTorch&#xff0c…

Vue 和 Spring boot 和 Bean 不同生命周期

一、Vue 组件生命周期 父子组件生命周期顺序&#xff1a; 创建时&#xff1a; 父 beforeCreate → 父 created → 父 beforeMount → 子组件生命周期 → 父 mounted 更新时&#xff1a; 父 beforeUpdate → 子组件更新 → 父 updated。 销毁时&#xff1a; 父 beforeDestroy…

Microsoft Azure 基础知识简介

Microsoft Azure 基础知识简介 已完成100 XP 2 分钟 Microsoft Azure 是一个云计算平台&#xff0c;提供一系列不断扩展的服务&#xff0c;可帮助你构建解决方案来满足业务目标。 Azure 服务支持从简单到复杂的一切内容。 Azure 具有简单的 Web 服务&#xff0c;用于在云中托…

C语言链接数据库

目录 使用 yum 配置 mysqld 环境 查看 mysqld 服务的版本 创建 mysql 句柄 链接数据库 使用数据库 增加数据 修改数据 查询数据 获取查询结果的行数 获取查询结果的列数 获取查询结果的列名 获取查询结果所有数据 断开链接 C语言访问mysql数据库整体源码 通过…

【Maven】手动安装依赖到本地仓库

【Maven】手动安装依赖到本地仓库 【一】下载依赖【二】安装 JAR 文件到本地仓库【三】验证安装【四】在项目中使用该依赖【1】注意事项【2】额外提示 【一】下载依赖 登录到中央仓库下载依赖&#xff0c;中央仓库地址&#xff1a;https://mvnrepository.com/ 搜搜你的依赖的a…

腾讯云golang一面

go垃圾回收机制 参考自&#xff1a;https://zhuanlan.zhihu.com/p/334999060 go 1.3 标记清除法 缺点 go 1.5 三色标记法 屏障机制 插入屏障 但是如果栈不添加,当全部三色标记扫描之后,栈上有可能依然存在白色对象被引用的情况(如上图的对象9). 所以要对栈重新进行三色标记扫…