当前位置: 首页 > news >正文

Android Activity 任务栈详解

1、什么是 Activity 任务栈

Activity 任务栈(Task Stack)是 Android 系统中用于管理 Activity 的后进先出(LIFO)栈结构。每个任务栈包含一组相关的 Activity,用户可以通过返回键在这些 Activity 之间导航。

2、LIFO原则 /后进先出

后进先出原则:LIFO 全称:Last In, First Out,顾名思义就是后进来的任务栈先出去。
1、当启动一个新的 Activity(通过 startActivity),这个新的 Activity 会被创建并压入(Pushed)当前任务栈的栈顶,这叫入栈(Push)
2、当用户按下返回键,当前位于栈顶的 Activity 会被销毁(Finish),并从栈中弹出(Popped)。然后,下一个(即之前的一个)Activity 会恢复并显示给用户,这叫出栈(Pop)

3、任务栈的基本结构

任务栈示例:
┌─────────────────┐
│   Activity D    │ ← 栈顶(当前显示)
├─────────────────┤
│   Activity C    │
├─────────────────┤
│   Activity B    │
├─────────────────┤
│   Activity A    │ ← 栈底(根Activity)
└─────────────────┘

4、任务栈的创建

1. 应用启动时创建

当用户点击应用图标时,系统会自动创建主任务栈。

// AndroidManifest.xml 中配置主Activity
<activityandroid:name=".MainActivity"android:label="@string/app_name"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter>
</activity>

2. 通过 Intent Flag 创建新任务栈

// 创建新任务栈
Intent intent = new Intent(this, NewTaskActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);// 创建新任务栈并清除现有栈
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

3. 使用 taskAffinity 创建不同任务栈

<!-- AndroidManifest.xml 中配置 -->
<activityandroid:name=".DocumentActivity"android:taskAffinity="com.example.app.document"android:launchMode="standard">
</activity>
// 启动具有不同affinity的Activity
Intent intent = new Intent(this, DocumentActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

5、Launch Mode 对任务栈的影响

1. standard(标准模式)

// 默认模式,每次启动都创建新实例
Intent intent = new Intent(this, StandardActivity.class);
startActivity(intent);
  • 总是创建新实例
  • 放入当前任务栈栈顶
  • 不影响任务栈结构

2. singleTop(栈顶复用)

// 如果已在栈顶则复用,否则创建新实例
Intent intent = new Intent(this, SingleTopActivity.class);
startActivity(intent);
  • 栈顶已存在则调用onNewIntent()
  • 不在栈顶则创建新实例

3. singleTask(栈内复用)

// 在指定affinity任务栈中寻找,清除其上所有Activity
Intent intent = new Intent(this, SingleTaskActivity.class);
startActivity(intent);
  • 在指定affinity任务栈中寻找实例
  • 如果存在则清除其上所有Activity并调到栈顶
  • 如果不存在则创建新实例

4. singleInstance(单实例)

// 创建新的任务栈,且该栈中只能有这一个Activity
Intent intent = new Intent(this, SingleInstanceActivity.class);
startActivity(intent);
  • 创建新的任务栈
  • 该栈中只能包含这一个Activity
  • 其他Activity不能进入这个栈

6、 任务栈的销毁

1. 正常返回销毁

// 按返回键销毁当前Activity
@Override
public void onBackPressed() {super.onBackPressed(); // 销毁当前Activity,返回上一个
}

2. 程序化销毁单个Activity

// 销毁当前Activity
finish();// 销毁后返回结果
setResult(RESULT_OK);
finish();

3. 清除整个任务栈

// 方法一:使用Intent Flag
Intent intent = new Intent(this, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);// 方法二:使用finishAffinity()
finishAffinity(); // 销毁当前任务栈中所有同affinity的Activity// 方法三:使用finishAndRemoveTask()
finishAndRemoveTask(); // 销毁Activity并移除任务栈

4. 清除部分任务栈

// 清除到指定Activity
Intent intent = new Intent(this, TargetActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);// 如果TargetActivity是singleTask,会清除其上的所有Activity

7、任务栈的管理和查询

1. 获取当前任务信息

// 获取ActivityManager
ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);// 获取当前任务ID
int taskId = getTaskId();
Log.d("TaskInfo", "当前任务ID: " + taskId);// 获取任务栈中的Activity数量
int numActivities = getNumActivitiesInTask();

2. 检查任务栈中的Activity

public boolean isActivityInTask(Class<?> activityClass) {ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {List<ActivityManager.AppTask> tasks = activityManager.getAppTasks();for (ActivityManager.AppTask task : tasks) {ActivityManager.RecentTaskInfo taskInfo = task.getTaskInfo();if (taskInfo.baseActivity != null && taskInfo.baseActivity.getClassName().equals(activityClass.getName())) {return true;}}}return false;
}

3. 任务栈状态监听

// 在Application中注册Activity生命周期回调
public class MyApp extends Application {private List<Activity> activityStack = new ArrayList<>();@Overridepublic void onCreate() {super.onCreate();registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {@Overridepublic void onActivityCreated(Activity activity, Bundle savedInstanceState) {activityStack.add(activity);Log.d("TaskStack", "Activity创建: " + activity.getClass().getSimpleName());}@Overridepublic void onActivityDestroyed(Activity activity) {activityStack.remove(activity);Log.d("TaskStack", "Activity销毁: " + activity.getClass().getSimpleName());}// 其他生命周期方法...});}public List<Activity> getActivityStack() {return new ArrayList<>(activityStack);}
}

8、实际应用场景

1. 登录流程管理

// 登录成功后清除登录相关Activity
private void loginSuccess() {Intent intent = new Intent(this, MainActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);startActivity(intent);finish();
}

2. 深度链接处理

// 处理深度链接,清理中间页面
private void handleDeepLink(Uri uri) {Intent intent = new Intent(this, ProductDetailActivity.class);intent.setData(uri);intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);startActivity(intent);
}

3. 退出应用

// 完全退出应用
public void exitApp() {finishAffinity(); // 关闭所有同affinity的ActivitySystem.exit(0);   // 完全退出进程
}// 或者
public void exitApp() {Intent intent = new Intent(this, MainActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(intent);finishAndRemoveTask();
}

9、注意事项

  1. 权限问题:查询其他任务栈可能需要特殊权限
  2. 版本兼容性:不同Android版本的任务栈行为可能不同
  3. 用户体验:合理使用任务栈管理,避免破坏用户导航预期
  4. 内存管理:及时销毁不需要的Activity,避免内存泄漏

10、 调试技巧

// 查看当前任务栈信息
private void dumpTaskStack() {ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {List<ActivityManager.AppTask> tasks = activityManager.getAppTasks();for (int i = 0; i < tasks.size(); i++) {ActivityManager.RecentTaskInfo taskInfo = tasks.get(i).getTaskInfo();Log.d("TaskDump", "Task " + i + ": " + "base=" + (taskInfo.baseActivity != null ? taskInfo.baseActivity.getClassName() : "null") +", top=" + (taskInfo.topActivity != null ? taskInfo.topActivity.getClassName() : "null"));}}
}
http://www.dtcms.com/a/363838.html

相关文章:

  • 一种简单而有效的融合时空特征嵌入的城区多变量长序列风速预测模型
  • 基于Springboot和Vue的前后端分离项目
  • MD5加密算法详解与实现
  • Python-Flask企业网页平台深度Q网络DQN强化学习推荐系统设计与实现:结合用户行为动态优化推荐策略
  • Dockerfile 自动化构建容器镜像
  • OpenStack:典型的面向服务架构(Service-Oriented Architecture, SOA)
  • Java Bitmap 去重:原理、代码实现与应用
  • 广东省省考备考(第九十二天9.2)——言语(刷题巩固第一节课)
  • 从全栈开发到微服务架构:一次真实的Java全栈面试经历
  • 子进程、父进程
  • 高效数据传输的秘密武器:Protobuf
  • Linux系统:进程信号的处理
  • TKDE-2022《Low-Rank Linear Embedding for Robust Clustering》
  • 【机器学习深度学习】向量模型与重排序模型:RAG 的双引擎解析
  • 利用 Java 爬虫获取淘宝商品 SKU 详细信息实战指南
  • keycloak中对接oidc协议时设置prompt=login
  • 机器学习回顾——决策树详解
  • SOL中转转账教程
  • Android Binder 驱动 - Media 服务启动流程
  • TiDB v8.5.3 单机集群部署指南
  • rocketmq启动与测试
  • 数据结构--跳表(Skip List)
  • playwright+python UI自动化测试中实现图片颜色和像素对比
  • 便携式显示器怎么选?:6大关键指标全解析
  • 【三班网】初三大事件
  • ELK 统一日志分析系统部署与实践指南(上)
  • 【C++上岸】C++常见面试题目--数据结构篇(第十七期)
  • Oracle 数据库与操作系统兼容性指南
  • LeetCode 31. 下一个排列
  • 机器人抓取中的力学相关概念解释