【问题标题】:Android - Is it possible to determine if an activity was started from another task?Android - 是否可以确定活动是否从另一个任务开始?
【发布时间】:2013-01-27 07:57:03
【问题描述】:

这是相当详尽的,所以我会尽量清楚。目前,我的应用程序在启动时需要重新加载一些数据。我在主要活动的 onCreate/onRestart 方法中加载这些数据。但是,如果用户从不离开当前任务,我需要小心不要重新加载数据。

例如,如果我需要从我的主要活动启动内置的联系人应用程序来选择一个联系人,那么我的主要活动将在我选择一个新联系人时暂停/停止。当我回到我的主要活动时,将调用 onRestart。在这种情况下,因为我从未离开过应用程序的任务,所以我不想重新加载数据。这意味着需要在此处包含一些检查,以确定用户是否直接从联系人应用程序返回而未离开它。

否则,如果用户在联系人应用程序打开时退出并从启动器菜单(或最近的应用程序列表等)重新启动该应用程序 - 我想关闭联系人应用程序并在主要活动时重新加载数据onRestart 方法被调用。

有没有办法在不使用任何可怕的用户权限(例如 GET_TASKS)的情况下做到这一点。我已经被这个问题困扰了很长时间,所以任何帮助都将不胜感激:)

Tyvm, B.坎贝尔

【问题讨论】:

  • 使用contentprovidersloaders 可以帮助你。您无需手动重新加载数据。
  • 您好,感谢您的回复。我知道我的用例有点不寻常,但我只想在活动开始(或重新启动)时重新加载数据。 ContentProviders 是非常有用的工具,但在这种情况下并非如此。
  • 另外,我认为这里不需要代码。这更像是一个 is-this-possible 和理论上-how-would-you-do-it 类型的问题,而不是 here-is-my-code-can-you-fix-it 类型的问题。不过,如果您认为对您有帮助,我可以提供一些代码?
  • 你能试试getTaskId()吗?我将它用于其他目的,但我希望它可以帮助你。返回值将在活动的生命周期内保持不变(如文档所述)。

标签: android android-activity task lifecycle


【解决方案1】:

我从 Android 文档中学到了很多:

Tasks and Back Stack

Navigation with Back and Up

Application Structure

这里有一些亮点:

任务是用户在什么时候与之交互的活动的集合 执行某项工作。活动被安排在一个堆栈中( “back stack”),按照每个活动的打开顺序。

当当前活动开始另一个活动时,新活动被推送 在堆栈的顶部并获得焦点。之前的活动依旧 在堆栈中,但被停止。当活动停止时,系统 保留其用户界面的当前状态。当用户按下 后退按钮,当前活动从顶部弹出 堆栈(活动被销毁)并且之前的活动恢复 (其 UI 的先前状态已恢复)。堆栈中的活动 永远不会重新排列,只会从堆栈中推送和弹出 - 推送 由当前活动启动并弹出时进入堆栈 当用户使用后退按钮离开时。

这意味着当你的应用程序pick up a contact时,任务中的活动堆栈可能是:

|联系人中的活动 A |

|应用中的活动 B |

|其他应用中的Activity C|

当用户通过按 Home 按钮离开任务时,当前 活动停止,其任务进入后台。系统 保留任务中每个活动的状态。如果用户稍后 通过选择开始任务的启动器图标来恢复任务, 任务来到前台并恢复顶部的活动 堆栈的。

即使用户在联系人应用程序打开时退出并从启动器菜单或最近的应用程序列表重新启动该应用程序,活动堆栈仍然与我们在上面看到的一样。可能使您的活动从另一个任务开始的唯一可能性是另一个应用程序(可能是启动器应用程序),它通过 startActivity 标志在新任务中启动主要活动,这是一种罕见的情况。在这种罕见的情况下,您可以通过Binder.getCallinguid() 简单地检查启动您活动的应用程序的uid 以区分它。

基于 cmets 编辑:

您可以检查FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY是否从历史记录中打开了活动:

if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0){

}else{

}

你也可以看看:

android:excludeFromRecents 如果您不希望您的应用从最近的应用开始

android:finishOnTaskLaunch

android:stateNotNeeded

【讨论】:

  • 我相信您可以覆盖此行为。例如,由于我希望联系人应用程序仅在前台存在时才存在,因此我可以使用以下代码启动联系人活动: Intent contactsIntent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);联系人Intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); getActivity().startActivityForResult(contactsIntent, 1234);这意味着当我恢复我的任务时,用户会立即看到我的活动,而不是按照您的示例看到联系人活动。
  • 那你为什么让它没有历史?
  • 大声笑,我也想知道这个。根据我必须遵循的规范,当用户从启动器(或最近的应用程序列表)启动应用程序时,需要首先显示主要活动并需要加载数据。在这种情况下,我无法显示联系人活动
  • 那我觉得FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET是你真正想要的。
  • 是的,我之前已经读过。它几乎准确地描述了我想要使用一些电子邮件示例的内容。但是,如果您使用“最近的应用程序”列表返回应用程序,很遗憾,它不起作用。它只是显示联系人应用程序,就好像什么都没发生一样。
【解决方案2】:

如果您正在加载的数据与application 生命周期相关而不是特定的activity,您可以在application 类中加载它,因此除非您的应用程序任务被终止,否则它不会再次重新加载。

【讨论】:

  • 在这种情况下,它是特定于活动的。我想我之前有点困惑,我现在已经编辑了一点,希望它更有意义一些。基本上我想在每次启动 Activity 时重新加载数据,除非我启动另一个 Activity 以获得结果并直接从该 Activity 返回(即直接,我的意思是他们从未退出第二个 Activity)
猜你喜欢
  • 2011-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多