18

launchModelauncher activitymanifest被忽略吗?android文档说默认值是“launchMode标准”,但如果这将应用于应用程序的主要活动,这对我来说不是逻辑,因为每次启动应用程序时,task都会在应用程序中创建另一个instance

4

5 回答 5

10

好吧,我自己深入研究了 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应用程序中指定的(或省略为默认行为),并忽略此属性。

我认为这表明文档不够清晰(或完整)。如果没有对核心源代码进行如此深入的调查,每个人都会不时得到意想不到的结果。

于 2015-12-20T23:03:20.770 回答
8

你混淆了两件事。一个是launchMode,另一个是“当用户从主屏幕选择一个应用程序图标,或者从最近的任务列表中选择一个任务时会发生什么”。这是两个完全不同的东西。

launchMode

每个Activity都有一个指定launchMode的(默认是"standard"or 。"multiple"这告诉 Android 如何启动 this Activity,并且有许多因素可以促成对launchMode.Intent在哪个任务上请求启动Activity(或者如果启动是从非活动上下文请求的,例如从 aServiceBroadcastReceiver)。这取决于Activity指定任务中的现有实例是否已经处于活动状态等。

从主屏幕或已安装应用程序列表中选择应用程序图标时的行为

当用户选择一个应用程序图标时,startActivity()会使用Intent 包含以下数据的调用:

  • 动作=主要
  • 类别=发射器
  • 组件设置为包名和Activity在清单中定义为 ACTION=MAIN 和 CATEGORY=LAUNCHER的类名
  • 标记FLAG_ACTIVITY_NEW_TASKFLAG_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,以获取有关一般任务重设的非常详细的解释。

于 2015-12-23T17:00:47.983 回答
2

将除打开活动之外的所有内容都视为抽象实现。将活动声明为

        <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 中编写。

于 2015-12-23T00:19:05.823 回答
0

你是对的。默认模式是“标准”。

根据android文档

*在standard模式下,每次“标准”活动有新的意图时,都会创建一个新的类实例来响应该意图。每个实例处理一个意图。

*.如果父activity有启动模式standard(并且upintent不包含FLAG_ACTIVITY_CLEAR_TOP),当前activity和它的父activity都被弹出栈,并且创建父activity的一个新实例来接收导航intent。

于 2015-12-23T05:26:20.020 回答
0

设置为标准模式的 Activity 的行为是始终创建一个新的 Activity 以与每个发送的 Intent 单独工作。想象一下,如果发送 10 个 Intent 来撰写一封电子邮件,那么应该有 10 个活动启动来分别为每个 Intent 提供服务。因此,设备中可能会启动无限数量的此类活动。

Android pre-Lollipop 上的行为

将创建标准Activity 并将其放置在与发送 Intent 的任务相同的任务中的堆栈顶部。例如,当我们将图像从图库共享到标准 Activity 时,尽管它们来自不同的应用程序,但它将被堆叠在与描述相同的任务中。如果我们将应用程序切换到另一个应用程序,然后再切换回 Gallery,我们仍然会看到标准的 launchMode 位于 Gallery 任务的顶部。因此,如果我们需要对 Gallery 做任何事情,我们必须首先完成那个额外的 Activity 中的工作。

在此处输入图像描述

Android Lollipop 上的行为

如果活动来自同一个应用程序,它将像在棒棒糖之前一样工作,堆叠在任务之上。但是如果 Intent 是从不同的应用程序发送的。将创建新任务,并将新创建的 Activity 放置为如下所示的根 Activity。

在此处输入图像描述

来源从这里

于 2015-12-23T11:48:00.810 回答