Intent.FLAG_ACTIVITY_CLEAR_TASK 和 Intent.FLAG_ACTIVITY_TASK_ON_HOME 的区别

Posted

技术标签:

【中文标题】Intent.FLAG_ACTIVITY_CLEAR_TASK 和 Intent.FLAG_ACTIVITY_TASK_ON_HOME 的区别【英文标题】:Difference between Intent.FLAG_ACTIVITY_CLEAR_TASK and Intent.FLAG_ACTIVITY_TASK_ON_HOME 【发布时间】:2014-03-17 00:05:58 【问题描述】:

来自 android 文档:

FLAG_ACTIVITY_CLEAR_TASK

如果在传递给 Context.startActivity() 的 Intent 中设置,此标志将 导致与活动相关联的任何现有任务 在活动开始之前被清除。也就是活动 成为一个空任务的新根,任何旧的 活动结束。这只能与 FLAG_ACTIVITY_NEW_TASK。

FLAG_ACTIVITY_TASK_ON_HOME

如果在传递给 Context.startActivity() 的 Intent 中设置,此标志将 导致新启动的任务被放置在当前家的顶部 活动任务(如果有的话)。也就是说,从任务中退缩 即使这不是最后一次,也将始终将用户送回家 他们看到的活动。这只能与 FLAG_ACTIVITY_NEW_TASK。

考虑这两个 sn-ps:

Intent intent = new Intent(this, Activity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

Intent intent = new Intent(this, Activity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
startActivity(intent);

按照我的理解,在任一代码 sn-p 中,我们都会创建一个新任务,其中只有 Activity,当您按下返回时,您会转到主屏幕。假设我可能弄错了,两者之间有什么区别?另外,如果我有另一个带有Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_TASK_ON_HOME | Intent.FLAG_ACTIVITY_CLEAR_TASK 的 sn-p,那会怎么样?

【问题讨论】:

【参考方案1】:

2个sn-ps之间是有区别的。以下是一些重要的背景信息:

一个任务包含一堆活动。任务可以在前台或后台。

任务也是“堆叠”的。如果您在任务A 中并开始一个新任务B,则任务B 将堆叠在任务A 之上。如果用户在任务B 中按下 BACK 键的次数足够多,他最终会回到任务 A。这是标准的 Android 行为。

你的sn-p...

Intent intent = new Intent(this, Activity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

...会做以下事情之一,具体取决于...

    如果Activity与当前任务具有相同的任务亲和性(即:执行此代码的任务),它将清除当前任务(完成任务中的所有活动)并启动@的新实例987654328@ 进入当前任务。如果用户按下 BACK 键,这将完成 Activity 并完成当前任务(因为任务中只有 1 个活动)并将用户返回到主屏幕或启动此任务的任务(任务位于任务堆栈中此任务的下方)。 如果Activity 具有与当前任务不同的任务关联,并且已经存在具有该任务关联的现有任务(即:Activity 将属于的现有任务),则将现有任务带到清除前台(任务中的所有活动都已完成),在任务的根目录中创建 Activity 的新实例,并将此任务放在当前任务之上(这样当 Activity 完成时,用户被退回到当前任务中)。 如果Activity 的任务亲和性与当前任务不同,并且不存在具有该任务亲和性的现有任务,则会创建一个新任务并在任务的根目录下创建一个Activity 的新实例,并且此任务置于当前任务之上(这样当Activity 完成时,用户将被退回到当前任务中)。

这段代码sn-p...

Intent intent = new Intent(this, Activity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
startActivity(intent);

...将根据...执行以下其中一项操作

    如果Activity 与当前任务具有相同的任务亲和性(即:执行此代码的任务)并且Activity 是当前任务的根活动,这将什么也不做。它不会启动新任务,不会清除任何活动,不会创建Activity 的新实例,也不会改变当前任务完成时发生的行为(即:如果当前任务由另一个任务启动,当当前任务中的所有活动都完成后,它会将用户拉回到任务堆栈中的上一个任务中。 如果Activity 与当前任务具有相同的任务亲和性(即:执行此代码的任务)并且Activity 不是当前任务的根活动,则此将简单地创建一个Activity 的新实例并将其放在当前任务中的当前活动之上。它不会启动新任务,不会清除任何活动,也不会改变当前任务完成时发生的行为(即:如果当前任务由另一个任务启动,当当前任务中的所有活动任务完成后,它会将用户放回到任务堆栈中的上一个任务中)。 如果Activity 具有与当前任务不同的任务关联,并且已经存在具有该任务关联的现有任务(即:Activity 将属于的现有任务)并且Activity 是根活动该现有任务,然后该现有任务被带到前台,该任务与任务堆栈分离(即:当该任务中的所有活动完成时,它会将用户返回到主屏幕并且不 到启动该任务的任务)。 如果Activity 具有与当前任务不同的任务亲和性,并且已经存在具有该任务亲和性的现有任务(即:Activity 将属于的现有任务)并且Activity不是该现有任务的根活动,然后将该现有任务带到前台并且该任务与任务堆栈分离(即:当该任务中的所有活动完成时,它会将用户返回到HOME 屏幕,不是启动该任务的任务),并创建 Activity 的新实例并将其置于该任务中任何现有活动的顶部。 如果Activity 具有与当前任务不同的任务亲和性,并且不存在具有该任务亲和性的现有任务,则会创建一个新任务并在任务的根目录创建一个Activity 的新实例,并且新任务与任务堆栈分离(这样当Activity 完成时,用户将返回主屏幕,而返回到启动它的任务)。

最后,这个 sn-p...

Intent intent = new Intent(this, Activity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
startActivity(intent);

...会做以下其中一件事情,具体取决于...

    如果Activity与当前任务具有相同的任务亲和性(即:执行此代码的任务),它将清除当前任务(完成任务中的所有活动)并启动@的新实例987654356@ 进入当前任务。如果用户按下 BACK 键,这将完成 Activity 并完成当前任务(因为任务中只有 1 个活动)并将用户返回到主屏幕。 如果Activity 具有与当前任务不同的任务亲和性,并且已经存在具有该任务亲和性的现有任务(即:Activity 将属于的现有任务),则将现有任务带到清除前台(任务中的所有活动都已完成),在任务的根目录创建Activity 的新实例,并将此任务与任务堆栈分离(这样当Activity 完成时,用户是返回主屏幕)。 如果Activity 具有与当前任务不同的任务亲和性,并且不存在具有该任务亲和性的现有任务,则会创建一个新任务并在任务的根目录下创建一个Activity 的新实例,并且此任务与任务堆栈分离(因此当Activity 完成时,用户将返回到主屏幕)。

我意识到这个答案很长而且很复杂,但是有很多不同的情况。我可能还没有涵盖所有可能的情况(例如,如果Activity 具有特殊的启动模式)...

【讨论】:

很好的解释。请注意,IMO,在标志组合 NEW_TASK 和 ON_HOME 的第 4 项中,还创建了 Activity 实例。也许你可能错过了。 @zgulser 感谢您的评论。在您所指的描述中,我确实写了“......并且创建了一个新的Activity实例......”。很抱歉你错过了。

以上是关于Intent.FLAG_ACTIVITY_CLEAR_TASK 和 Intent.FLAG_ACTIVITY_TASK_ON_HOME 的区别的主要内容,如果未能解决你的问题,请参考以下文章