中launchMode的launcher activity会manifest被忽略吗?android文档说默认值是“launchMode标准”,但如果这将应用于应用程序的主要活动,这对我来说不是逻辑,因为每次启动应用程序时,task都会在应用程序中创建另一个instance。
5 回答
好吧,我自己深入研究了 Android 资源,发现了以下内容。
启动器使用startActivityAsUser. LauncherAppsService意图是使用这些行构造的:
Intent launchIntent = new Intent(Intent.ACTION_MAIN);
launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
launchIntent.setComponent(component);
launchIntent.setSourceBounds(sourceBounds);
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
根据 Android 文档,该标志FLAG_ACTIVITY_NEW_TASK意味着:
使用此标志时,如果您现在正在启动的 Activity 已经在运行任务,则不会启动新的 Activity;相反,当前任务将简单地以其上次所处的状态被带到屏幕的前面。
这有效且无条件地覆盖launchMode应用程序中指定的(或省略为默认行为),并忽略此属性。
我认为这表明文档不够清晰(或完整)。如果没有对核心源代码进行如此深入的调查,每个人都会不时得到意想不到的结果。
你混淆了两件事。一个是launchMode,另一个是“当用户从主屏幕选择一个应用程序图标,或者从最近的任务列表中选择一个任务时会发生什么”。这是两个完全不同的东西。
launchMode
每个Activity都有一个指定launchMode的(默认是"standard"or 。"multiple"这告诉 Android 如何启动 this Activity,并且有许多因素可以促成对launchMode.Intent在哪个任务上请求启动Activity(或者如果启动是从非活动上下文请求的,例如从 aService或BroadcastReceiver)。这取决于Activity指定任务中的现有实例是否已经处于活动状态等。
从主屏幕或已安装应用程序列表中选择应用程序图标时的行为
当用户选择一个应用程序图标时,startActivity()会使用Intent 包含以下数据的调用:
- 动作=主要
- 类别=发射器
- 组件设置为包名和
Activity在清单中定义为 ACTION=MAIN 和 CATEGORY=LAUNCHER的类名 - 标记
FLAG_ACTIVITY_NEW_TASK并FLAG_ACTIVITY_RESET_TASK_IF_NEEDED设置。
无论要启动的launchMode定义如何,使用这样的Activity调用都会导致以下行为:startActivity()Intent
如果已经有一个任务关联与Activity正在启动的任务匹配(简单来说,如果应用程序已经在运行),Android 将简单地将现有任务带到前台。而已。它不会创建任何Activity. 它不调用onNewIntent()任何Activity. 除了将现有任务置于前台之外,它什么也不做。这就是为什么即使您指定launchMode="standard"了您的启动器Activity,Android 也不会在您每次单击应用程序图标时创建一个新实例。
如果还没有一个任务关联与Activity正在启动的任务匹配的现有任务(简单来说,如果应用程序尚未运行),Android 将创建一个新任务并启动该Activity任务。launchMode在这里不起作用,因为在将单个启动Activity到新任务时启动模式之间绝对没有区别。Android 总是会创建一个新任务,并且总是会创建一个新的实例Activity作为该任务的根。
当用户从最近的任务列表中选择一个任务时,此行为也是相同的。如果任务仍在运行,Android 只是将任务带到前台,不启动任何新Activity实例并且不调用onNewIntent(). 如果任务不再运行,Android 会创建一个新任务并将启动器启动Activity到该任务中。这里唯一的区别是如果用户从最近的任务列表中选择了一个任务,该标志FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY也被设置。Intent
我希望这回答了你的问题。
请参阅此答案FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,以获取有关一般任务重设的非常详细的解释。
将除打开活动之外的所有内容都视为抽象实现。将活动声明为
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
将导致它首先打开。在形成 Intent 以在活动之间导航时,将覆盖后续活动。覆盖表示为意图标志。
意图附加列表:http: //developer.android.com/reference/android/content/Intent.html
使用标志作为命令,否则您将在 Manifest 中编写。
你是对的。默认模式是“标准”。
根据android文档
*在
standard模式下,每次“标准”活动有新的意图时,都会创建一个新的类实例来响应该意图。每个实例处理一个意图。*.如果父activity有启动模式
standard(并且upintent不包含FLAG_ACTIVITY_CLEAR_TOP),当前activity和它的父activity都被弹出栈,并且创建父activity的一个新实例来接收导航intent。
设置为标准模式的 Activity 的行为是始终创建一个新的 Activity 以与每个发送的 Intent 单独工作。想象一下,如果发送 10 个 Intent 来撰写一封电子邮件,那么应该有 10 个活动启动来分别为每个 Intent 提供服务。因此,设备中可能会启动无限数量的此类活动。
Android pre-Lollipop 上的行为
将创建标准Activity 并将其放置在与发送 Intent 的任务相同的任务中的堆栈顶部。例如,当我们将图像从图库共享到标准 Activity 时,尽管它们来自不同的应用程序,但它将被堆叠在与描述相同的任务中。如果我们将应用程序切换到另一个应用程序,然后再切换回 Gallery,我们仍然会看到标准的 launchMode 位于 Gallery 任务的顶部。因此,如果我们需要对 Gallery 做任何事情,我们必须首先完成那个额外的 Activity 中的工作。
Android Lollipop 上的行为
如果活动来自同一个应用程序,它将像在棒棒糖之前一样工作,堆叠在任务之上。但是如果 Intent 是从不同的应用程序发送的。将创建新任务,并将新创建的 Activity 放置为如下所示的根 Activity。
来源从这里

