在 Android 开发中,继承 android.app.Activity 和 androidx.activity.ComponentActivity 有着非常巨大的区别。
简单来说:android.app.Activity 是最基础的老古董,而 androidx.activity.ComponentActivity 是现代 Android 开发(Jetpack 架构)的基石。 在现在的开发中,我们几乎永远不会直接继承 android.app.Activity。
以下是它们的核心区别:
1. 对现代架构组件(Jetpack)的支持
这是最大的区别。
-
android.app.Activity:它仅仅是 Android 操作系统提供的一个基础窗口容器。它不知道什么是 ViewModel,也不知道什么是 Lifecycle(生命周期感知)。
-
ComponentActivity:它天生内置了对 Jetpack 架构组件的支持。它实现了 LifecycleOwner、ViewModelStoreOwner 和 SavedStateRegistryOwner。
-
ViewModel 支持:在 ComponentActivity 中,你可以直接使用 viewModels() 委托来轻松获取 ViewModel,并且 ViewModel 可以在屏幕旋转时自动存活。
-
Lifecycle 支持:你可以让其他类直接观察这个 Activity 的生命周期(lifecycle.addObserver(...)),从而解耦代码。
-
2. 是否支持 Jetpack Compose (现代 UI 框架)
-
android.app.Activity:完全不支持 Jetpack Compose。
-
ComponentActivity :它是 Jetpack Compose 的标准底层容器。如果你在用 Compose 写 UI,你必须继承它,因为启动 Compose UI 的 setContent { } 方法就是作为 ComponentActivity 的扩展函数存在的。
3. 处理页面返回结果(Activity Result API)
-
android.app.Activity :如果你要启动另一个页面并获取结果(比如打开相册选图),你需要使用老旧的 startActivityForResult(),然后在臃肿的 onActivityResult() 回调里写各种 if/else 请求码判断。这种老方法官方已经废弃 (Deprecated)。
-
ComponentActivity :提供了现代的 Activity Result API。你可以使用 registerForActivityResult,以回调或协程的方式极其优雅地处理权限请求、页面返回结果,代码高内聚且类型安全。
4. 现代的返回键/手势拦截
-
android.app.Activity:要拦截返回键,你需要重写 onBackPressed() 方法。这种写法在现代 Android 的"预测性返回手势"(Predictive Back Gesture)下表现很差。
-
ComponentActivity:内置了 OnBackPressedDispatcher。你可以在 Activity、Fragment 甚至 Compose 的任意位置动态注册和注销返回事件拦截,而不是全部挤在 Activity 的重写方法里。
继承关系图
为了更直观地理解,你可以看看它们的家族继承谱系:
code Text
downloadcontent_copy
expand_less
java.lang.Object
↳ android.app.Activity (最基础的系统级 Activity,不要直接用)
↳ androidx.core.app.ComponentActivity (底层兼容处理,通常不直接用)
↳ androidx.activity.ComponentActivity (🌟纯 Compose 项目的标准父类,Jetpack 的核心)
↳ androidx.appcompat.app.AppCompatActivity (🌟传统的 XML 项目/混合项目标准父类,增加了老版本主题和 UI 控件的兼容)
总结:我该怎么选?
-
如果你在写纯 Jetpack Compose 的新项目 :
直接继承 ComponentActivity。它是最轻量级且功能完备的选择。
code Kotlin
downloadcontent_copy
expand_lessclass MainActivity : ComponentActivity() { ... } -
如果你在使用传统的 XML 布局(View 系统) :
应该继承 AppCompatActivity(它是 ComponentActivity 的子类,多加了对旧版本 Android UI 主题的兼容代码)。
code Kotlin
downloadcontent_copy
expand_lessclass MainActivity : AppCompatActivity() { ... } -
什么时候继承 android.app.Activity?
永远不要。 除非你在维护一个十年前、连 AndroidX 都没有引入的超级老旧项目,或者你在写极度精简的底层系统应用并且极其苛刻地要求包体积(不能引入任何 AndroidX 依赖)。