Android 活动(Activity)(保姆级教程)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观
在 Android 开发的浩瀚海洋中,"Android 活动(Activity)" 是开发者必须掌握的核心概念之一。它如同应用程序的窗口,承载着用户与设备交互的每一帧画面。无论是展示登录界面、处理表单数据,还是构建复杂的导航逻辑,Activity 都是实现这些功能的基础单元。本文将从 Activity 的基本原理、生命周期管理、启动模式到数据传递等维度,结合代码示例和形象比喻,帮助开发者系统性地理解这一概念,并在实际项目中灵活运用。
一、什么是 Android 活动(Activity)?
Activity 是 Android 系统中用于承载用户界面的组件,可以将其想象为一座“房间”,每个房间代表应用中的一个独立功能场景。例如,登录界面、商品详情页、设置面板等,都可视为不同的 Activity。
核心特性
- 用户交互入口:Activity 是用户直接操作的界面载体,所有按钮点击、输入框交互均通过 Activity 实现。
- 生命周期管理:每个 Activity 会经历创建、运行、暂停、销毁等状态,开发者需在这些阶段处理资源分配与释放。
- 堆栈式管理:Activity 按“后进先出”原则存放在任务栈中,确保用户返回操作的流畅性。
比喻:
可以把 Activity 理解为电影院的放映厅。每个放映厅(Activity)播放不同的电影(功能),观众(用户)通过检票口(Intent)进入特定厅,而影院经理(系统)负责管理所有放映厅的开放与关闭状态。
二、Activity 的生命周期详解
Activity 的生命周期由系统严格控制,开发者需在关键回调方法中执行特定操作。以下是核心状态转换图:
状态 | 描述 | 典型应用场景 |
---|---|---|
onCreate() | Activity 被创建时调用,用于初始化视图和数据。 | 加载布局、绑定数据源 |
onStart() | Activity 变为可见但尚未获取焦点时触发。 | 准备监听器或开始动画 |
onResume() | Activity 获得用户交互权限,处于可操作状态。 | 恢复网络请求、开始传感器监听 |
onPause() | Activity 失去焦点,可能被新 Activity 覆盖。 | 保存用户输入数据、暂停动画 |
onStop() | Activity 完全不可见,可能被销毁。 | 释放资源(如摄像头、文件句柄) |
onDestroy() | Activity 被系统回收前最后调用的方法。 | 彻底释放所有资源 |
生命周期代码示例
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化视图和数据
Log.d("Lifecycle", "onCreate: 页面创建");
}
@Override
protected void onStart() {
super.onStart();
Log.d("Lifecycle", "onStart: 页面可见");
}
@Override
protected void onResume() {
super.onResume();
Log.d("Lifecycle", "onResume: 页面可交互");
}
@Override
protected void onPause() {
super.onPause();
Log.d("Lifecycle", "onPause: 页面暂停");
}
@Override
protected void onStop() {
super.onStop();
Log.d("Lifecycle", "onStop: 页面不可见");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("Lifecycle", "onDestroy: 页面销毁");
}
}
关键点提醒:
- 资源管理:避免在 onCreate() 中执行耗时操作,如网络请求或复杂计算,可改用异步线程。
- 数据保存:在 onSaveInstanceState() 中保存临时数据,防止 Activity 被意外销毁后数据丢失。
三、Activity 的启动模式(Launch Mode)
启动模式决定了 Activity 的实例化方式和任务栈的管理策略。Android 提供了四种核心模式:
1. Standard(标准模式)
默认模式,每次启动都会创建新实例,堆栈中可存在多个相同 Activity。
场景:浏览商品列表时,点击每个商品进入详情页,可使用此模式。
<!-- AndroidManifest.xml 配置 -->
<activity
android:name=".DetailActivity"
android:launchMode="standard" />
2. SingleTop(单实例栈顶复用)
若目标 Activity 已位于任务栈顶部,则直接复用,否则创建新实例。
场景:连续点击通知栏多次跳转同一页面时,避免重复创建。
// 启动 Activity 时的 Intent 标志
Intent intent = new Intent(this, DetailActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
3. SingleTask(单实例任务栈)
系统会为该 Activity 创建独立的任务栈,且同一栈内仅保留一个实例。
场景:应用入口 Activity,防止重复启动。
<activity
android:name=".MainActivity"
android:launchMode="singleTask" />
4. SingleInstance(全局单实例)
仅创建一个实例,并且该实例存在于独立的任务栈中,全局唯一。
场景:系统级服务类应用(如拨号器),需与其他应用完全隔离。
比喻:
启动模式如同交通规则:
- Standard 是普通车道,允许重复通行;
- SingleTop 是单行道入口,若已有车辆在前则并线;
- SingleTask 是专用通道,仅允许一辆车通行;
- SingleInstance 是私人车道,与其他车道完全隔离。
四、Activity 间数据传递与返回结果
1. 显式 Intent 传递基础数据
通过 Intent 的 putExtra() 方法传递简单数据类型(如 String、int)。
// 发送方
Intent intent = new Intent(CurrentActivity.this, TargetActivity.class);
intent.putExtra("user_id", 123);
intent.putExtra("username", "Alice");
startActivity(intent);
// 接收方
Intent intent = getIntent();
int userId = intent.getIntExtra("user_id", 0);
String username = intent.getStringExtra("username");
2. 使用 Bundle 传递复杂对象
若需传递自定义对象,需实现 Serializable 或 Parcelable 接口。
// 定义 Parcelable 对象
public class User implements Parcelable {
private String name;
private int age;
// Parcelable 实现代码略...
}
// 发送方
User user = new User("Bob", 25);
Intent intent = new Intent(this, ProfileActivity.class);
intent.putExtra("user", user);
// 接收方
User user = (User) intent.getParcelableExtra("user");
3. 启动 Activity 并获取返回结果
通过 startActivityForResult() 启动 Activity,并在 onActivityResult() 中接收结果。
// 发送方
Intent intent = new Intent(this, EditActivity.class);
startActivityForResult(intent, 1001);
// 接收结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1001 && resultCode == RESULT_OK) {
String editedText = data.getStringExtra("edited_data");
}
}
// 接收方返回数据
Intent resultIntent = new Intent();
resultIntent.putExtra("edited_data", "修改后的文本");
setResult(RESULT_OK, resultIntent);
finish();
五、Activity 的内存优化与进阶技巧
1. 避免内存泄漏
当 Activity 被销毁后,若存在未释放的引用(如线程、监听器),可能导致内存泄漏。
// 错误示例:未取消的异步任务
new Thread(() -> {
// 网络请求后调用 UI 操作
runOnUiThread(() -> textView.setText("加载完成"));
}).start();
// 正确做法:在 onDestroy() 中取消任务
@Override
protected void onDestroy() {
super.onDestroy();
if (task != null && !task.isCancelled()) {
task.cancel(true);
}
}
2. 配合 ViewModel 保存状态
使用 AndroidX 的 ViewModel 类,可跨配置变化(如屏幕旋转)保存数据。
// 定义 ViewModel
public class MainViewModel extends ViewModel {
private MutableLiveData<String> username = new MutableLiveData<>();
public LiveData<String> getUsername() {
return username;
}
}
// Activity 中使用
MainViewModel viewModel = new ViewModelProvider(this).get(MainViewModel.class);
viewModel.getUsername().observe(this, username -> {
// 更新 UI
});
3. 任务栈管理优化
通过 Intent 标志控制 Activity 的启动行为:
// 清空当前任务栈,以新 Activity 为根
Intent intent = new Intent(this, NewActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
六、常见问题与解决方案
1. Activity 重复创建问题
现象:旋转屏幕或从后台返回时,页面数据丢失。
解决方案:在 onSaveInstanceState() 中保存数据,并在 onCreate() 中恢复。
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("text", editText.getText().toString());
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
String text = savedInstanceState.getString("text");
editText.setText(text);
}
}
2. Activity 堆栈溢出
现象:频繁跳转导致内存占用过高。
解决方案:使用 SingleTop 或 SingleTask 模式,或在跳转时指定 FLAG_ACTIVITY_CLEAR_TOP 标志。
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
结论
Android 活动(Activity)是构建应用界面的核心组件,其生命周期管理、启动模式选择和数据交互能力,直接影响着用户体验与系统资源效率。开发者需深入理解 Activity 的运行机制,并通过合理的设计(如 ViewModel、启动标志)规避常见问题。随着 Jetpack 组件(如 Navigation Component)的普及,Activity 的使用场景虽有所变化,但其作为 Android 架构基石的地位仍不可替代。建议读者结合官方文档与开源项目,持续探索更复杂的场景实现。
延伸学习:
- 阅读《Android 开发艺术探索》中关于 Activity 生命周期的章节
- 实践 Navigation 组件在 Jetpack 体系中的 Activity 管理
- 探索 Process 生命周期对 Activity 的影响