Android Activity全面解析:从创建到生命周期的完整指南
Activity作为Android四大组件之一,是构建用户界面的核心单元。笔者通过郭霖著的
第一行代码
入门安卓,内容基本都取自书中,这篇博客作为笔者的笔记同时精简了一些书中内容分享在csdn中
一、Activity的创建与基础配置
1.1 创建Activity的基本步骤
在Android项目中创建一个Activity需要遵循以下步骤:
- 定义Java类:新建一个继承自
Activity
或其子类(如AppCompatActivity
)的Java类 - 注册到清单文件:在
AndroidManifest.xml
中声明Activity,并配置必要的属性(如launchMode
) - 绑定布局:在
onCreate()
中调用setContentView(R.layout.xxx)
加载界面布局
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main); // 绑定布局}
}
在实际开发中,Android Studio会自动完成大部分配置工作。我们只需在Java目录下创建Activity,IDE会自动生成必要的XML配置。
1.2 Context的理解与应用
Activity继承自Context
类,这是一个抽象类,代表应用程序的环境信息,提供以下核心功能:
- 访问应用程序资源(如字符串、图片等)
- 启动其他组件(Activity、Service等)
- 获取系统服务(如布局填充器、通知服务等)
在Activity内部使用this
即可获取Context对象,但在内部类中需要使用ActivityName.this
来避免混淆。
1.3 Toast的合理使用
Toast用于向用户显示短暂的提示信息,会自动消失且不干扰用户操作:
Button button = findViewById(R.id.button);
button.setOnClickListener(v -> {Toast.makeText(MainActivity.this, "操作成功", Toast.LENGTH_SHORT).show();
});
二、Activity的销毁机制
2.1 finish()方法详解
调用finish()
方法会触发Activity的销毁流程:
- 生命周期回调顺序:
onPause()
→onStop()
→onDestroy()
- 系统最终会释放资源并移除Activity实例
重要特性:
finish()
不会立即终止当前方法的执行,后续代码仍会正常执行- 它只是标记Activity为待销毁状态,系统会在当前方法执行完毕后处理销毁操作
- 如果不调用
finish()
,Activity会保留在返回栈中,可能占用内存资源
button.setOnClickListener(v -> {finish(); // 标记销毁Log.d("TEST", "这行代码仍会执行"); // 正常输出startActivity(new Intent(this, NextActivity.class));
});
2.2 销毁场景分析
场景 | 是否自动调用finish() | 备注 |
---|---|---|
用户按返回键 | 是 | 系统默认处理 |
调用startActivity启动新Activity | 否 | 旧Activity保留在栈中 |
配置变更(如旋转屏幕) | 是(但会重建) | 系统自动处理 |
内存不足被系统回收 | 是 | 不可预测 |
三、Activity间的切换与数据传递
1 显式Intent切换Activity
显式Intent明确指定要启动的目标Activity类:
Intent intent = new Intent(CurrentActivity.this, TargetActivity.class);
startActivity(intent);
特点:
- 明确知道要启动哪个Activity
- 代码耦合性较高
- 适用于应用内部跳转
2 隐式Intent切换Activity
隐式Intent通过指定action、category等信息,由系统匹配合适的Activity:
<!-- AndroidManifest.xml中配置 -->
<activity android:name=".TargetActivity" android:exported="true"><intent-filter><action android:name="com.example.ACTION_TARGET"/><category android:name="android.intent.category.DEFAULT"/></intent-filter>
</activity>
还可以跳转到网页上,指定Intent的action为Intent.ACTION_VIEW
,然后通过Uri.parse()方法将网址字符串解析成Uri对象,再调用Intent的setData方法将该Uri对象传递进去。
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.first_layout);Button bt1 = findViewById(R.id.button1);bt1.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(MainActivity.this, "提醒一下", Toast.LENGTH_SHORT).show();finish();Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("https://www.quark.cn/s/JHK6vrGF1K12Y0Nl52?from=kkframenew_resultsearch&uc_param_str=ntnwvepffrbiprsvchutosstxs&by=submit&q=%E5%94%90%E4%BA%BA&queryId=h5FJGAyNpZHUOP9W0M9ypNrZ8Sxncku32B8QU6h4TDKLYwGehGZhZ35QkEgGGcqA0cWn4bVJAJDup1bvTQJ53ojFoMG12Bn1H11uPKOD0soRtrKZCUSFGJSGHK2sn"));startActivity(intent);}});
应用场景:
- 启动其他应用的Activity(如分享功能)
- 实现应用内模块解耦
- 处理系统广播和通知
传递数据
1.向下一个活动传递数据
Intent中提供了一系列putExtra()方法的重载,可以把向传递的数据暂存在Intent中,启动另一个活动后只需要把数据再从Intent中取出就可以了。比如MainActivity中有一个字符串,想把字符串传递到SecondaryActivity中,运行如下代码后可以在logcat中直接看到传递的Hello,world
(xml文件中各加一个Button即可)。其中putExtra第一个参数相当于一个键,第二个参数是要传递的数据。
package com.example.myapplication;import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Log.d("MainActivity:", this.toString());setContentView(R.layout.first_layout);Button bt1 = findViewById(R.id.button1);bt1.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String data = "Hello, world";Intent intent = new Intent(MainActivity.this, SecondaryActivity.class);intent.putExtra("main_data", data);startActivity(intent);}});}
}
接受数据的活动代码中,先调用getIntent()
得到该intent对象,然后用getStringExtra
得到该数据。
package com.example.myapplication;import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;import androidx.activity.EdgeToEdge;
import androidx.annotation.LongDef;
import androidx.appcompat.app.AppCompatActivity;public class SecondaryActivity extends AppCompatActivity {private static final String TAG = "SecondaryActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Log.d("SecondaryActivity:", this.toString());EdgeToEdge.enable(this);setContentView(R.layout.activity_secondary);Button button = findViewById(R.id.btn2);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = getIntent();String data = intent.getStringExtra("main_data");Log.d("SecondaryActivity", data);}});}@Overrideprotected void onStop() {super.onStop();Log.d(TAG, "onStop: ");}@Overrideprotected void onDestroy() {super.onDestroy();Log.d(TAG, "onDestroy: ");}
}
2.返回数据给上一个活动
返回上一个活动只需要一个back键,并没有启动活动的intent来传递数据,但是Activity中有一个startActivityForResult()
也是用来启动活动的。该方法接收两个参数,第一个参数是Intent
,第二个参数是一个请求码,用于在之后的回调中判断数据来源.
package com.example.myapplication;import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Log.d("MainActivity:", this.toString());setContentView(R.layout.first_layout);Button bt1 = findViewById(R.id.button1);bt1.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String data = "Hello, world";Intent intent = new Intent(MainActivity.this, SecondaryActivity.class);startActivityForResult(intent, 1);}});}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);switch (requestCode) {case 1:if (resultCode == RESULT_OK) {String returnedData = data.getStringExtra("data_return");Log.d( "First_Activity", returnedData);}break;default:}}
}
下面是另一个活动的代码,我们还是构建一个Intent,但仅用来传递数据而不指定任何"意图"切换活动,然后用setResult
方法向上一个活动返回数据,接收两个参数,第一个用于向上一个互动返回处理结果,一般使用RESULT_OK
和RESULT_CANCELD
两个值,第二个则把带有数据的Intent传递回去,然后用finish销毁该活动以返回上一个活动。由于使用startActivityForResult
启动活动,,在第二个活动被销毁后会回调上一个活动的onActivityResult()
方法,因此需要重写第一个活动中这个方法得到返回的数据。该方法有三个参数,第一个参数resultCode
,即传入的请求码,第二个参数resultCode
是返回的处理结果,第三个参数data即携带返回数据的Intent
。
package com.example.myapplication;import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;import androidx.activity.EdgeToEdge;
import androidx.annotation.LongDef;
import androidx.appcompat.app.AppCompatActivity;public class SecondaryActivity extends AppCompatActivity {private static final String TAG = "SecondaryActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Log.d("SecondaryActivity:", this.toString());EdgeToEdge.enable(this);setContentView(R.layout.activity_secondary);Button button = findViewById(R.id.btn2);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent();intent.putExtra("data_return", "Hello, world");setResult(RESULT_OK, intent);finish();}});}@Overrideprotected void onStop() {super.onStop();Log.d(TAG, "onStop: ");}@Overrideprotected void onDestroy() {super.onDestroy();Log.d(TAG, "onDestroy: ");}
}
四、Activity的生命周期管理
4.1 Activity的四种状态
-
运行状态(Active/Running):
- 位于栈顶,可见且可交互
- 系统最不可能回收的状态
-
暂停状态(Paused):
- 不再处于栈顶但仍部分可见
- 如被对话框式Activity覆盖时
- 系统可能在内存紧张时回收
-
停止状态(Stopped):
- 完全不可见
- 仍保留状态和成员变量
- 系统可能回收内存
-
销毁状态(Destroyed):
- 被系统回收或调用finish()
- 需要重建才能再次使用
4.2 生命周期回调方法
Activity类定义了7个核心回调方法:
-
onCreate()
:- 首次创建时调用
- 完成初始化(加载布局、绑定数据等)
- 必须调用
super.onCreate()
-
onStart()
:- 由不可见变为可见时调用
- 适合启动动画、注册监听器等
-
onResume()
:- 进入可交互状态
- 恢复暂停时被停止的功能(如相机)
-
onPause()
:- 失去焦点,部分可见
- 必须快速执行(不能做耗时操作)
- 保存持久性数据
-
onStop()
:- 完全不可见
- 适合释放不必要资源
-
onDestroy()
:- 被销毁前调用
- 释放所有资源,避免内存泄漏
-
onRestart()
:- 由停止状态重新启动时调用
- 后接
onStart()
4.3 生命周期场景分析
启动Activity: onCreate -> onStart -> onResume
按下Home键: onPause -> onStop
返回应用: onRestart -> onStart -> onResume
回退退出: onPause -> onStop -> onDestroy
对话框式Activity的影响:
- 只会触发
onPause()
,不会触发onStop()
- 底层Activity仍部分可见
五、Activity的启动模式
在AndroidManifest.xml
中通过android:launchMode
属性配置:
5.1 standard(标准模式)
- 默认模式
- 每次启动都创建新实例
- 允许多个相同Activity实例存在
- 典型的栈内管理方式
<activity android:name=".StandardActivity" android:launchMode="standard"/>
5.2 singleTop(栈顶复用)
- 如果目标Activity已在栈顶,则复用实例
- 避免重复创建相同Activity
- 适用于通知跳转等场景
<activity android:name=".SingleTopActivity"android:launchMode="singleTop"/>
5.3 singleTask(栈内复用)
- 整个任务栈中只存在一个实例
- 如果已存在,则清除其上的所有Activity
- 适合应用的主页Activity
<activity android:name=".MainActivity"android:launchMode="singleTask"/>
5.4 singleInstance(单例模式)
- 启用独立的返回栈管理
- 保证只有一个实例存在
- 多个应用共享同一个Activity实例
- 适合闹钟等系统级功能
<activity android:name=".AlarmActivity"android:launchMode="singleInstance"/>