当您单击应用程序的启动图标时会发生啥?
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
仅在活动设置了singleTask
、singleInstance
启动模式时才会传递。如果活动设置了singleTop
启动模式或启动活动的意图设置了标志FLAG_ACTIVITY_SINGLE_TOP
并且活动实例已经位于目标任务的顶部,它也会被传递。这意味着尝试启动新的活动实例,而不是现有实例本身需要处理意图。
以下是对您的询问的回复:
是否总是发送新的意图,或者结果有时与 从最近的任务中恢复任务?
如果任务已在运行,则将其置于前台。如果FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
标志被用来启动一个活动,然后任务被带到前台,那么这个活动就会被杀死。来自docs:
这对于您的逻辑中断的情况很有用 应用。例如,一个电子邮件应用程序可能有一个命令 查看附件,它会启动要显示的图像查看活动 它。此活动应该是电子邮件应用程序任务的一部分, 因为它是用户参与的任务的一部分。但是,如果 用户离开该任务,然后从家里选择电子邮件应用程序, 我们可能希望他们回到他们正在查看的对话,而不是 图片附件,因为这令人困惑。通过设置此标志 启动图像查看器时,该查看器及其任何活动 下次用户返回邮件时将删除starts。
-
如果一个意图被发送,它什么时候被发送到 onCreate() 方法 一个新的活动实例,它什么时候被路由通过 现有活动的 onNewIntent()?
onCreate
在创建新的活动实例时被调用。如果已经存在活动实例并且不需要创建新实例,则调用 onNewIntent
,例如 singleInstance
、singleTask
和有条件的 singleTop
(如上所述)。
假设意图通过 onNewIntent() 路由 任务中的现有活动。它被发送到哪个活动?这 离顶部最近的还是离根最近的?会不会一直得到 发送到应用程序启动活动的实例,或者它可以 有时会被发送到与根具有相同亲和力的活动? 它可以发送到不共享相同的活动吗 亲和为根?
如果是singleTask
和singleInstance
,它必须是任务的根。对于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以上是关于当您单击应用程序的启动图标时会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章