当您单击应用程序的启动图标时会发生啥?

Posted

技术标签:

【中文标题】当您单击应用程序的启动图标时会发生啥?【英文标题】:What happens when you click on an application's launch icon?当您单击应用程序的启动图标时会发生什么? 【发布时间】:2014-10-25 00:55:20 【问题描述】:

当您点击应用的启动图标时会发生什么?

    是否始终发送新意图,或者结果有时与从最近的任务中恢复任务相同?

    如果一个意图被发送,它什么时候被发送到一个新的活动实例的 onCreate() 方法,什么时候它通过一个现有活动的 onNewIntent() 被路由?

    假设意图通过任务中现有活动的 onNewIntent() 进行路由。它被发送到哪个活动?离顶部最近的还是离根最近的?它总是会被发送到应用程序启动活动的实例,还是有时会被发送到与根具有相同亲和力的活动?是否可以将其发送到与根不具有相同亲和力的活动?

    最后,这一切是如何受任务中活动的各种启动模式(标准、单顶、单实例、单任务)影响的?

如果有谁明白这一切,请帮助我!

【问题讨论】:

我想你可以深入研究ActivityManager的源代码。 【参考方案1】:
What happens when you click on an app's launch icon?

启动器应用调用 startActivity 的意图 [action = Intent.ACTION_MAIN, category = Intent.CATEGORY_LAUNCHER 和 flag = Intent.FLAG_ACTIVITY_NEW_TASK]。

关于Intent.FLAG_ACTIVITY_NEW_TASK,来自docs:

当使用这个标志时,如果一个任务已经在为这个活动运行 您现在正在开始,则不会开始新的活动; 相反,当前任务将简单地被带到前面 屏幕上的状态。

onNewIntent 基础知识:

onNewIntent 仅在活动设置了singleTasksingleInstance 启动模式时才会传递。如果活动设置了singleTop 启动模式或启动活动的意图设置了标志FLAG_ACTIVITY_SINGLE_TOP 并且活动实例已经位于目标任务的顶部,它也会被传递。这意味着尝试启动新的活动实例,而不是现有实例本身需要处理意图。

以下是对您的询问的回复:

是否总是发送新的意图,或者结果有时与 从最近的任务中恢复任务?

如果任务已在运行,则将其置于前台。如果FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET 标志被用来启动一个活动,然后任务被带到前台,那么这个活动就会被杀死。来自docs:

这对于您的逻辑中断的情况很有用 应用。例如,一个电子邮件应用程序可能有一个命令 查看附件,它会启动要显示的图像查看活动 它。此活动应该是电子邮件应用程序任务的一部分, 因为它是用户参与的任务的一部分。但是,如果 用户离开该任务,然后从家里选择电子邮件应用程序, 我们可能希望他们回到他们正在查看的对话,而不是 图片附件,因为这令人困惑。通过设置此标志 启动图像查看器时,该查看器及其任何活动 下次用户返回邮件时将删除starts。

-

如果一个意图被发送,它什么时候被发送到 onCreate() 方法 一个新的活动实例,它什么时候被路由通过 现有活动的 onNewIntent()?

onCreate 在创建新的活动实例时被调用。如果已经存在活动实例并且不需要创建新实例,则调用 onNewIntent,例如 singleInstancesingleTask 和有条件的 singleTop(如上所述)。

假设意图通过 onNewIntent() 路由 任务中的现有活动。它被发送到哪个活动?这 离顶部最近的还是离根最近的?会不会一直得到 发送到应用程序启动活动的实例,或者它可以 有时会被发送到与根具有相同亲和力的活动? 它可以发送到不共享相同的活动吗 亲和为根?

如果是singleTasksingleInstance,它必须是任务的根。对于singleTop,它必须是任务的最高活动。

最后,这一切如何受到各种启动模式的影响 (标准、单顶、单实例、单任务)的活动 在任务中?

我希望到目前为止提供的解释,回答它。

更新 1:

这是将标志添加到意图的Launcher 代码:

void processShortcut(Intent intent) 
    ....
    Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
    mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
    ....


void startActivitySafely(Intent intent) 
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    ...
    startActivity(intent);

【讨论】:

这是一个很好的答案。通过在 onCreate() 和 onNewIntent() 方法中记录 Integer.toHexString(intent.getFlags()) 的值,您会发现实际上有比您提到的更多的标志。您在 onCreate() 中获得值 0x10200000,在 onNewIntent() 中获得值 0x10600000。这意味着总是有 2 个标志 FLAG_ACTIVITY_NEW_TASK 和 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,对于 singleTask 和 singleInstance 也有标志 FLAG_ACTIVITY_BROUGHT_TO_FRONT。 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 的存在非常好,因为它证实了您所说的关于 FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET 的内容。 我希望我能在文档中找到设置了哪些标志的位置。知道这一点非常重要,因为其中一些具有绝对毁灭性的影响! 我还不能奖励赏金,但如果我在接下来的 11 小时内没有发现任何其他标志打乱了这个解释,那么 100 分就是你的了! @pbabcdefp 文档指定为 singleTaskMode 设置了 FLAG_ACTIVITY_BROUGHT_TO_FRONT。我们将不得不深入研究 Intent 文档以了解更多信息。顺便说一句,谢谢你的问题,我学得很好。【参考方案2】:

您最好阅读此处的开发者文档:http://developer.android.com/training/basics/activity-lifecycle/index.html

第一课中有一个流程图(http://developer.android.com/images/training/basics/basic-lifecycle.png),它提供了一个很好的 Android 活动生命周期的图形表示。

【讨论】:

谢谢,但我的问题更多是关于任务而不是个人活动。遗憾的是,文档甚至没有开始解释其中的任何工作原理。 当您提到任务时,您指的是活动集合吗? developer.android.com/guide/components/… 是的,我是。任务就像一堆活动,但在文档中解释得很差。这个答案,尤其是它链接的幻灯片,其中包含大量非常有用的信息***.com/a/17873524/403255

以上是关于当您单击应用程序的启动图标时会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何测试当您将应用更新发布到市场时会发生啥

当您尝试在迭代列表元素时删除它时会发生啥

当您在浏览器中输入 URL 时会发生啥 [关闭]

当您在具有相同基类的派生类之间进行动态转换时会发生啥?

当您达到 SQL Server Express 4GB / 10GB 限制时会发生啥?

启动包含 Flow 注释的 React 应用程序时会发生啥?