Android中FLAG_ACTIVITY_CLEAR_TASK的作用

转:http://laokaddk.blog.51cto.com/368606/1363827 


FLAG_ACTIVITY_CLEAR_TASK :如果在调用Context.startActivity时传递这个标记,将会导致任何用来放置该activity的已经存在的task里面的已经存在的activity先清空,然后该activity再在该task中启动,也就是说,这个新启动的activity变为了这个空tas的根activity.所有老的activity都结束掉。该标志必须和FLAG_ACTIVITY_NEW_TASK一起使用。

示例:

我们有三个activity:MainActivity、ActivityA、ActivityB. 依次从MainActivity中启动ActivityA,从ActivityA中启动ActivityB.

首先我们所有的都使用缺省的,也即没有设置taskAffinity、launchMode,启动activity时Intent也不带标记,我们看一下启动B之后的堆栈:


  1. ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)    

  2.  Main stack:    

  3.    TaskRecord{4199dd68 #56 A com.leaves.ipanel U 0}    

  4.    Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.leaves.ipanel/.MainActivity }    

  5.      Hist #3: ActivityRecord{4140fdf8 u0 com.leaves.ipanel/.ActivityB}    

  6.        Intent { act=com.leaves.ipanel.ActivityB cmp=com.leaves.ipanel/.ActivityB }    

  7.        ProcessRecord{41517e80 13350:com.leaves.ipanel/u0a10061}    

  8.      Hist #2: ActivityRecord{413ff7e8 u0 com.leaves.ipanel/.ActivityA}    

  9.        Intent { act=com.leaves.ipanel.ActivityA cmp=com.leaves.ipanel/.ActivityA }    

  10.        ProcessRecord{41517e80 13350:com.leaves.ipanel/u0a10061}    

  11.      Hist #1: ActivityRecord{413f8b28 u0 com.leaves.ipanel/.MainActivity}    

  12.        Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.leaves.ipanel/.MainActivity }    

  13.        ProcessRecord{41517e80 13350:com.leaves.ipanel/u0a10061}    

  14.    TaskRecord{41350f60 #2 A com.android.launcher U 0}    

  15.    Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10600000 cmp=com.android.launcher/com.android.launcher2.Launcher }    

  16.      Hist #0: ActivityRecord{41616790 u0 com.android.launcher/com.android.launcher2.Launcher}    

  17.        Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000000 cmp=com.android.launcher/com.android.launcher2.Launcher }    

  18.        ProcessRecord{41615818 628:com.android.launcher/1000}    

可以看到三者在同一个task中,且都存在。



接下来我们在启动ActivityB时添加FLAG_ACTIVITY_CLEAR_TASK和FLAG_ACTIVITY_NEW_TASK

  1. publicvoid onClick(View v) {    

  2. // TODO Auto-generated method stub  

  3.    Log.i(TAG, "--onClick--task id = " + getCurrentTaskId());      

  4.    Intent intent = new Intent("com.leaves.ipanel.ActivityB");      

  5.    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);    

  6.    startActivity(intent);    

  7. }    

再看下启动ActivityB之后的堆栈:


  1. ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)    

  2.  Main stack:    

  3.    TaskRecord{4245bd10 #57 A com.leaves.ipanel U 0}    

  4.    Intent { act=com.leaves.ipanel.ActivityB flg=0x10008000 cmp=com.leaves.ipanel/.ActivityB }    

  5.      Hist #1: ActivityRecord{413f8b28 u0 com.leaves.ipanel/.ActivityB}    

  6.        Intent { act=com.leaves.ipanel.ActivityB flg=0x10008000 cmp=com.leaves.ipanel/.ActivityB }    

  7.        ProcessRecord{41413010 13441:com.leaves.ipanel/u0a10061}    

  8.    TaskRecord{41350f60 #2 A com.android.launcher U 0}    

  9.    Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10600000 cmp=com.android.launcher/com.android.launcher2.Launcher }    

  10.      Hist #0: ActivityRecord{41616790 u0 com.android.launcher/com.android.launcher2.Launcher}    

  11.        Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000000 cmp=com.android.launcher/com.android.launcher2.Launcher }    

  12.        ProcessRecord{41615818 628:com.android.launcher/1000}    

可以看到,MainActivity和ActivityA都被结束掉了,原因就是因为该task用来装载ActivityB,而启动时又设置了FLAG_ACTIVITY_CLEAR_TASK和FLAG_ACTIVITY_NEW_TASK
### FLAG_ACTIVITY_CLEAR_TASK 的含义及其在 Android 任务管理中的作用 #### 一、FLAG_ACTIVITY_CLEAR_TASK 的基本定义 `FLAG_ACTIVITY_CLEAR_TASK` 是一个用于清除任务栈中所有现有活动的标志位。当带有此标志的 `Intent` 被用来启动一个新的 `Activity` 时,系统会在新 `Activity` 启动前清空与其关联的任务栈内的所有旧有 `Activity` 实例[^2]。换句话说,一旦设置了该标志,在同一个任务栈中存在的任何先前的 `Activity` 都会被销毁,仅保留即将被启动的新 `Activity`。 --- #### 二、FLAG_ACTIVITY_CLEAR_TASK 的工作原理 通常情况下,`FLAG_ACTIVITY_CLEAR_TASK` 不单独使用,而是与 `FLAG_ACTIVITY_NEW_TASK` 组合在一起。这是因为只有在一个全新的任务环境下执行清理操作才显得合理且必要。组合后的功能表现为:先创建一个新的任务环境,接着在此基础上彻底清除原有任务栈的内容后再加载目标 `Activity`[^2]。 具体过程如下: 1. 如果当前存在未完成的任务,则将其完全移除。 2. 创建一个新的任务作为起点。 3. 在新建的任务中放置指定的目标 `Activity`。 这种机制特别适合于实现类似于注销账户后返回到应用首页这样的场景需求。 --- #### 三、典型应用场景解析 ##### 场景 1: 用户登出后的重定向处理 假设有一个应用程序支持用户登录状态管理和多级导航结构。当用户决定退出登录时,不仅需要关闭所有的敏感数据展示页面(比如个人资料编辑页),还需要确保整个系统的安全性和一致性。此时就可以采用以下策略: ```java Intent intent = new Intent(CurrentActivity.this, LoginActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(intent); ``` 上述代码片段实现了这样一个目的——无论用户之前访问了多少层嵌套菜单或者浏览过多少条消息记录,只要触发了“登出”按钮事件,就会立即跳转回登录界面,并同时抹平之前的足迹轨迹[^2]。 --- ##### 场景 2: 单入口模型的确立 有些类型的 APP 倾向于维持唯一的主屏幕入口点,即便用户可能从多种渠道进入应用内部的不同位置也是如此。例如闹钟提醒服务可能会直接唤醒特定的通知详情页,但如果用户再次手动打开应用则应该始终看到熟悉的主页布局而非随机停留在某个次要环节之上。这时也可以借助类似的技巧达到预期效果: ```java if (!isTaskRoot()) { Intent mainIntent = new Intent(this, MainActivity.class); mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(mainIntent); } ``` 这里的关键在于检测当前 `Activity` 是否为所在任务的第一项(`isTaskRoot`)。如果不是的话就强制调整方向指向预设好的标准起始位置[^3]。 --- #### 四、注意事项与最佳实践建议 尽管 `FLAG_ACTIVITY_CLEAR_TASK` 提供了一种强大的工具帮助简化复杂的状态转换流程,但也需要注意一些潜在的风险因素以免误用造成不良后果: - **谨慎评估适用范围**: 并非任何时候都适宜运用如此激进的方式重构任务层次关系。应当仔细权衡利弊得失再做定夺。 - **考虑用户体验连续性**: 过度频繁地刷新任务可能导致用户的迷失感加剧,因此需平衡好即时响应速度与长期记忆线索之间的矛盾冲突。 - **测试覆盖全面边界条件**: 对涉及此类高级特性的模块加强单元测试力度,验证极端情况下的表现是否符合预期。 --- ### 总结 综上所述,`FLAG_ACTIVITY_CLEAR_TASK` 主要在 Android 应用程序的任务管理系统扮演着至关重要的角色,尤其是在涉及到全局状态初始化或重要转折点的操作过程中发挥不可替代的作用。通过恰当配置相关联的其他辅助标记如 `FLAG_ACTIVITY_NEW_TASK`, 开发者能够灵活掌控应用的行为模式以适应多样化的业务诉求。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值