Activity 基础
Activity 是 Android 四大组件中最常用的一个,它代表一个具有用户界面的单一屏幕。理解 Activity 的生命周期和使用方式是 Android 开发的基础。
什么是 Activity?
Activity 可以理解为应用的一个"页面"或"屏幕"。一个应用通常由多个 Activity 组成,每个 Activity 负责展示特定的界面和处理用户的交互。例如,一个邮件应用可能有:
- 邮件列表 Activity:显示收件箱
- 邮件详情 Activity:显示邮件内容
- 写邮件 Activity:编辑新邮件
虽然现代 Android 开发推荐使用单 Activity 架构(配合 Fragment 和 Jetpack Compose),但理解 Activity 仍然是必要的。
创建 Activity
1. 创建 Activity 类
在 Android Studio 中,右键点击包名 → New → Activity → Empty Views Activity,会自动生成 Activity 类和对应的布局文件。
手动创建的步骤如下:
package com.example.myapp
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 初始化界面和逻辑
}
}
代码说明:
- 继承
AppCompatActivity而不是Activity,这样可以获得更好的兼容性和 Material Design 支持 onCreate()是 Activity 创建时调用的方法setContentView()设置 Activity 的布局文件
2. 创建布局文件
在 res/layout/ 目录下创建 activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, Android!"
android:textSize="24sp" />
<Button
android:id="@+id/btn_click"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点击我"
android:layout_marginTop="16dp" />
</LinearLayout>
3. 在清单文件中注册
所有 Activity 都必须在 AndroidManifest.xml 中注册:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.MyApp">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
关键属性说明:
android:name:Activity 的类名,.开头表示相对于包名android:exported:是否允许其他应用启动此 Activity<intent-filter>:定义 Activity 可以响应的 IntentMAIN+LAUNCHER:表示这是应用的启动 Activity
Activity 生命周期
理解生命周期是正确使用 Activity 的关键。Activity 在其生命周期中会经历多个状态转换。
生命周期回调方法
class MainActivity : AppCompatActivity() {
private val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d(TAG, "onCreate: Activity 创建")
}
override fun onStart() {
super.onStart()
Log.d(TAG, "onStart: Activity 即将可见")
}
override fun onResume() {
super.onResume()
Log.d(TAG, "onResume: Activity 获得焦点,可交互")
}
override fun onPause() {
super.onPause()
Log.d(TAG, "onPause: Activity 失去焦点")
}
override fun onStop() {
super.onStop()
Log.d(TAG, "onStop: Activity 不再可见")
}
override fun onDestroy() {
super.onDestroy()
Log.d(TAG, "onDestroy: Activity 即将销毁")
}
override fun onRestart() {
super.onRestart()
Log.d(TAG, "onRestart: Activity 重新启动")
}
}
生命周期状态图
三个嵌套循环
Activity 的生命周期可以分为三个嵌套循环:
1. 完整生命周期(Entire Lifetime)
从 onCreate() 到 onDestroy()。在这个期间,Activity 完成创建到销毁的全部过程。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 初始化资源、绑定数据
}
override fun onDestroy() {
// 释放资源
super.onDestroy()
}
2. 可见生命周期(Visible Lifetime)
从 onStart() 到 onStop()。在这个期间,Activity 对用户可见(可能无法交互)。
override fun onStart() {
super.onStart()
// 注册广播接收器、开始动画
}
override fun onStop() {
// 注销广播接收器、停止动画
super.onStop()
}
3. 前台生命周期(Foreground Lifetime)
从 onResume() 到 onPause()。在这个期间, Activity 处于前台,用户可以与之交互。
override fun onResume() {
super.onResume()
// 恢复暂停的操作、获取独占资源
}
override fun onPause() {
// 暂停操作、释放独占资源
super.onPause()
}
常见场景的生命周期变化
| 场景 | 生命周期调用顺序 |
|---|---|
| 启动应用 | onCreate → onStart → onResume |
| 按下返回键 | onPause → onStop → onDestroy |
| 按下 Home 键 | onPause → onStop |
| 从后台返回 | onRestart → onStart → onResume |
| 打开新 Activity | onPause → onStop |
| 关闭新 Activity 返回 | onRestart → onStart → onResume |
| 旋转屏幕 | onPause → onStop → onDestroy → onCreate → onStart → onResume |
Activity 之间的跳转
使用 Intent 启动 Activity
Intent 是 Android 中用于组件间通信的消息对象。使用 Intent 可以启动其他 Activity、发送广播、启动服务等。
// 在当前 Activity 中启动新 Activity
val intent = Intent(this, SecondActivity::class.java)
startActivity(intent)
传递数据
发送数据:
val intent = Intent(this, SecondActivity::class.java).apply {
putExtra("username", "张三")
putExtra("age", 25)
putExtra("is_member", true)
}
startActivity(intent)
接收数据:
class SecondActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
// 获取传递的数据
val username = intent.getStringExtra("username") ?: ""
val age = intent.getIntExtra("age", 0)
val isMember = intent.getBooleanExtra("is_member", false)
Log.d("SecondActivity", "用户: $username, 年龄: $age, 会员: $isMember")
}
}
传递复杂数据
对于复杂对象,需要实现 Serializable 或 Parcelable 接口:
// 使用 Parcelable(推荐,性能更好)
@Parcelize
data class User(
val id: Int,
val name: String,
val email: String
) : Parcelable
// 发送
val user = User(1, "张三", "[email protected]")
val intent = Intent(this, SecondActivity::class.java).apply {
putExtra("user", user)
}
startActivity(intent)
// 接收
val user = intent.getParcelableExtra<User>("user")
获取返回结果
当需要从目标 Activity 返回结果时,使用 startActivityForResult(已废弃)或新的 Activity Result API:
// 定义协定
val startForResult = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == RESULT_OK) {
val data = result.data?.getStringExtra("result")
Log.d("MainActivity", "返回结果: $data")
}
}
// 启动 Activity
val intent = Intent(this, SecondActivity::class.java)
startForResult.launch(intent)
在 SecondActivity 中返回结果:
// 设置返回结果
val resultIntent = Intent().apply {
putExtra("result", "操作成功")
}
setResult(RESULT_OK, resultIntent)
finish() // 关闭当前 Activity
Activity 的启动模式
Activity 的启动模式决定了 Activity 在任务栈中的行为。在 AndroidManifest.xml 中通过 android:launchMode 属性设置。
四种启动模式
1. standard(默认)
每次启动都创建新实例,放入任务栈顶部。
<activity
android:name=".MainActivity"
android:launchMode="standard" />
启动顺序: A → B → B → A
任务栈: [A, B, B, A]
2. singleTop
如果要启动的 Activity 已在栈顶,则复用该实例,调用 onNewIntent();否则创建新实例。
<activity
android:name=".MainActivity"
android:launchMode="singleTop" />
当前栈: [A, B, C]
启动 C: [A, B, C](复用栈顶 C,调用 onNewIntent)
启动 B: [A, B, C, B](创建新 B)
3. singleTask
在系统中只存在一个实例。如果已存在,则将其上方的所有 Activity 出栈,并调用 onNewIntent()。
<activity
android:name=".MainActivity"
android:launchMode="singleTask" />
当前栈: [A, B, C, D]
启动 B: [A, B](C、D 被出栈,B 调用 onNewIntent)
4. singleInstance
独占一个任务栈,系统中只有一个实例。其他应用也可以共享这个实例。
<activity
android:name=".MainActivity"
android:launchMode="singleInstance" />
处理 onNewIntent
对于 singleTop、singleTask、singleInstance 模式,需要处理 onNewIntent:
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
// 更新 Intent,处理新的启动参数
setIntent(intent)
val newData = intent.getStringExtra("new_data")
Log.d("MainActivity", "收到新数据: $newData")
}
Activity 状态保存与恢复
当系统因内存不足或配置变更(如屏幕旋转)销毁 Activity 时,需要保存和恢复状态。
保存状态
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
// 保存需要恢复的数据
outState.putString("username", username)
outState.putInt("score", score)
}
恢复状态
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 恢复保存的数据
if (savedInstanceState != null) {
username = savedInstanceState.getString("username", "")
score = savedInstanceState.getInt("score", 0)
}
}
// 或者使用 onRestoreInstanceState(在 onStart 之后调用)
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
username = savedInstanceState.getString("username", "")
score = savedInstanceState.getInt("score", 0)
}
使用 ViewModel(推荐)
对于复杂的状态管理,推荐使用 ViewModel:
class MainViewModel : ViewModel() {
private val _username = MutableLiveData<String>()
val username: LiveData<String> = _username
private val _score = MutableLiveData<Int>()
val score: LiveData<Int> = _score
fun setUsername(name: String) {
_username.value = name
}
fun setScore(value: Int) {
_score.value = value
}
}
class MainActivity : AppCompatActivity() {
private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// ViewModel 中的数据在配置变更时自动保留
viewModel.username.observe(this) { name ->
// 更新 UI
}
}
}
Activity 的常见任务
设置标题栏
// 设置标题
supportActionBar?.title = "我的页面"
// 隐藏标题栏
supportActionBar?.hide()
// 启用返回按钮
supportActionBar?.setDisplayHomeAsUpEnabled(true)
// 处理返回按钮点击
override fun onSupportNavigateUp(): Boolean {
onBackPressedDispatcher.onBackPressed()
return true
}
全屏模式
// 隐藏状态栏和导航栏
window.decorView.systemUiVisibility = (
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
or View.SYSTEM_UI_FLAG_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
)
// 使用 WindowInsetsController(API 30+)
window.insetsController?.hide(WindowInsets.Type.statusBars())
设置横竖屏
// 代码中设置
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE // 横屏
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT // 竖屏
// 或在清单文件中设置
<activity
android:name=".MainActivity"
android:screenOrientation="portrait" />
小结
本章介绍了 Activity 的核心概念:
- Activity 基础:创建 Activity、注册清单、设置布局
- 生命周期:理解七个回调方法和三种嵌套循环
- Activity 跳转:使用 Intent 启动和传递数据
- 启动模式:standard、singleTop、singleTask、singleInstance
- 状态保存:onSaveInstanceState 和 ViewModel
下一章将学习 Android 的布局系统,掌握如何构建美观的用户界面。