Activity基础概念
1. 定义与作用
- Android 四大组件之一,是用户界面的载体,负责与用户交互。
- 一个应用可包含多个 Activity,通过
Intent
切换。
2. 层次结构
- Activity 通常放在 任务栈(Task Stack) 中管理,遵循后进先出(LIFO)原则。
- 任务栈可跨应用,如从应用 A 启动应用 B 的 Activity,B 的 Activity 会加入 A 的任务栈。
3. Activity与Context的关系
- Activity 是 Context 的子类,可直接使用 Context 的方法(如
getResources()
、startActivity()
)。
java
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Study"
tools:targetApi="31">
<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 的类名称。您还可以添加属性 ,用于定义标签、图标或界面主题等 activity 特征。
Activity生命周期
一个 activity 在其生命周期中会经历多种状态。 您可以使用一系列回调来处理状态之间的转换。 developer.android.google.cn/guide/compo...

- onCreate ():Activity 首次创建时调用,用于初始化组件、设置布局等
- onStart ():Activity 即将可见时调用
- onResume ():Activity 获得焦点、可交互时调用
- onPause ():Activity 失去焦点、即将转入后台时调用
- onStop ():Activity 完全不可见时调用
- onRestart ():Activity 从停止状态重新启动时调用
- onDestroy ():Activity 被销毁时调用
常见问题
- Android Activity 重复调用 onCreate () 的原因
- 跳转时未调用 onDestroy () 的核心原因
- 屏幕旋转时生命周期变化
- 屏幕旋转时的完整生命周期流程
Activity启动模式
在 Android 开发中,Activity 的启动模式(Launch Mode)、任务(Task)和返回栈(Back Stack)是实现应用导航逻辑的核心概念。理解这些机制对于构建流畅的用户体验和优化内存管理至关重要。
1. 四种启动模式
启动模式 | 核心特性 | 应用场景 |
---|---|---|
standard | 每次启动都创建新实例,无论目标 Activity 是否已存在于栈中 | 默认模式,普通页面跳转 |
singleTop | 若目标 Activity 位于栈顶,则复用该实例;否则创建新实例 | 通知栏点击跳转、搜索结果页 |
singleTask | 任务内单实例:若目标 Activity 存在于栈中,则清除其上方所有 Activity | 应用主界面、浏览器主窗口 |
singleInstance | 全局单实例:独占一个任务栈,不与其他 Activity 共存 | 系统级应用(如来电界面) |
2. 启动模式设置
AndroidManifest.xml:
java
<activity
android:name=".StandardActivity"
android:launchMode="standard" />
Intent 标志位:
标志位 | 作用 |
---|---|
FLAG_ACTIVITY_NEW_TASK |
类似 singleTask,通常用于从非 Activity 上下文启动 Activity |
FLAG_ACTIVITY_SINGLE_TOP |
类似 singleTop,启动时若目标 Activity 在栈顶则复用 |
FLAG_ACTIVITY_CLEAR_TOP |
清除目标 Activity 上方的所有 Activity,通常与 NEW_TASK 配合使用 |
FLAG_ACTIVITY_REORDER_TO_FRONT |
将已存在的 Activity 移至栈顶,不创建新实例 |
java
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
3. 启动模式示例
1. standard 模式
ini
<activity
android:name=".StandardActivity"
android:launchMode="standard" />
行为 :每次启动都会创建新实例
任务栈变化:
css
初始栈:[MainActivity]
启动 StandardActivity:[MainActivity, StandardActivity]
再次启动:[MainActivity, StandardActivity, StandardActivity]
2. singleTop 模式
ini
<activity
android:name=".SingleTopActivity"
android:launchMode="singleTop" />
行为:
- 若目标 Activity 在栈顶:调用
onNewIntent()
而非创建新实例 - 若不在栈顶:创建新实例
任务栈变化:
css
初始栈:[MainActivity, SingleTopActivity]
再次启动 SingleTopActivity(在栈顶):[MainActivity, SingleTopActivity](复用)
启动其他 Activity:[MainActivity, SingleTopActivity, OtherActivity]
再次启动 SingleTopActivity(不在栈顶):[MainActivity, SingleTopActivity, OtherActivity, SingleTopActivity]
3. singleTask 模式
ini
<activity
android:name=".MainActivity"
android:launchMode="singleTask"
android:taskAffinity="com.example.app" />
行为:
- 若目标 Activity 不存在于任何任务:创建新任务并实例化
- 若存在:将该任务移至前台,并清除其上方所有 Activity
任务栈变化:
css
初始栈:[MainActivity, ActivityB, ActivityC]
启动 MainActivity(已存在):[MainActivity](清除 B 和 C)
4. singleInstance 模式
ini
<activity
android:name=".SingleInstanceActivity"
android:launchMode="singleInstance" />
行为:
- 目标 Activity 独占一个任务栈
- 该任务栈中永远只有这一个 Activity
任务栈变化:
css
初始任务 Task1:[MainActivity]
启动 SingleInstanceActivity:
Task1:[MainActivity]
Task2:[SingleInstanceActivity]
从 SingleInstanceActivity 启动 ActivityB:
Task1:[MainActivity, ActivityB]
Task2:[SingleInstanceActivity]
Activity 数据传递与回调
1. 数据传递方式
- Intent 携带数据:
java
// 创建 Intent 并添加参数
Intent intent = new Intent(CurrentActivity.this, TargetActivity.class);
intent.putExtra("key_string", "Hello World"); // 传递字符串
intent.putExtra("key_int", 123); // 传递整数
intent.putExtra("key_boolean", true); // 传递布尔值
// 传递自定义对象(需实现 Serializable 或 Parcelable 接口)
User user = new User("John", 25);
intent.putExtra("key_object", user);
// 启动 Activity
startActivity(intent);
java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_target);
// 获取启动该 Activity 的 Intent
Intent intent = getIntent();
// 从 Intent 中获取参数
String strValue = intent.getStringExtra("key_string");
int intValue = intent.getIntExtra("key_int", 0); // 第二个参数是默认值
boolean boolValue = intent.getBooleanExtra("key_boolean", false);
// 获取自定义对象
User user = (User) intent.getSerializableExtra("key_object");
}
- Bundle 传递复杂数据:
java
// 创建 Bundle 对象并添加数据
Bundle bundle = new Bundle();
bundle.putString("name", "Alice");
bundle.putInt("age", 30);
bundle.putStringArrayList("hobbies", new ArrayList<>(Arrays.asList("reading", "swimming")));
// 将 Bundle 放入 Intent
Intent intent = new Intent(CurrentActivity.this, TargetActivity.class);
intent.putExtras(bundle);
// 启动 Activity
startActivity(intent);
java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_target);
// 获取 Bundle
Bundle bundle = getIntent().();
if (bundle != null) {
String name = bundle.getString("name");
int age = bundle.getInt("age");
ArrayList<String> hobbies = bundle.getStringArrayList("hobbies");
}
}
- 静态变量:通过静态类或单例模式存储数据。
- ViewModel 共享数据 :在 Activity 间通过
ViewModel
共享数据(需配合 Jetpack)。
2. 数据回调方式
- 旧方式(已弃用) :
onActivityResult()
+startActivityForResult()
。 - 新方式(Activity Result API) :
java
ActivityResultLauncher<Intent> launcher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> { if (result.getResultCode() == RESULT_OK) {
Intent data = result.getData();
// 处理返回数据
}
});
// 启动 Activity
Intent intent = new Intent(this, SecondActivity.class);
launcher.launch(intent);
Activity UI 与布局
1. 加载布局的方式
setContentView(R.layout.activity_main)
:在onCreate()
中加载布局文件。- 动态加载布局:
java
LinearLayout root = findViewById(R.id.root_layout);
View childView = LayoutInflater.from(this).inflate(R.layout.child_layout, root, false);
root.addView(childView);
2. UI组件交互
- 查找 View:
findViewById()
或使用 Kotlin 的by viewBindings
。 - 设置监听器:
java
Button button = findViewById(R.id.button);
button.setOnClickListener(v -> { // 处理点击事件 });
3. Fragment 与 Activity 协作
- Activity 中添加 Fragment:
java
getSupportFragmentManager()
.beginTransaction()
.add(R.id.fragment_container, new MyFragment())
.commit();
- Fragment 与 Activity 通信:通过接口或
ViewModel
。
Activity状态管理
1. 临时状态保存
onSaveInstanceState(Bundle outState)
:在 Activity 可能被销毁前调用,保存临时数据(如文本框内容)。onRestoreInstanceState(Bundle savedInstanceState)
:在onCreate()
后恢复数据。
java
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// 获取保存的文本内容并恢复到文本框中
String myText = savedInstanceState.getString("my_text");
myEditText.setText(myText);
}
java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
// 恢复保存的数据
String myText = savedInstanceState.getString("my_text");
myEditText.setText(myText);
}
}
2. 配置变更处理
- 默认重建 :屏幕旋转等配置变更会导致 Activity 重建,需通过
savedInstanceState
恢复状态。 - 禁止重建 :在
AndroidManifest.xml
中设置android:configChanges="orientation|screenSize"
,并在onConfigurationChanged()
中处理变更。
java
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Log.d("MainActivity", "Orientation changed to Landscape");
setContentView(R.layout.activity_main_landscape);
// 恢复EditText的内容
if (savedUsername != null) {
etUsername = findViewById(R.id.et_username); // 需要重新获取EditText引用
etUsername.setText(savedUsername);
}
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
Log.d("MainActivity", "Orientation changed to Portrait");
setContentView(R.layout.activity_main);
// 恢复EditText的内容
if (savedUsername != null) {
etUsername = findViewById(R.id.et_username); // 重新获取EditText引用
etUsername.setText(savedUsername);
}
}
}
Activity常见问题
- Activity 生命周期的各个阶段及其作用?
- 屏幕旋转时 Activity 的重建过程及如何避免?
- Activity 启动模式的区别和应用场景?
- 如何在 Activity 间传递大数据(超过 1MB)?
- Activity 和 Fragment 的关系与区别?
- 如何优化 Activity 的启动速度?