【问题标题】:Is there any way to distinguish between an Android Activity onResume from the home screen?有什么方法可以区分 Android Activity onResume 和主屏幕吗?
【发布时间】:2011-01-25 02:03:07
【问题描述】:

有没有办法从主屏幕/启动器判断一个 Activity 是否正在恢复(即调用 onResume)?

例如,如果我有一个包含两个活动 A 和 B 的应用程序。

场景 1: Activity A 上的某些用户操作将调用 Activity B,将其带到前台 - 将 Activity A 移动到后台。当 Activity A 进入后台时,它会通过 onPause() 和 onStop()。用户(现在在 Activity B 上)要么完成 Activity,要么点击“返回”按钮,将 Activity A 带回前台,导致 onRestart()、onStart()、onResume() 序列。

场景 2: 如果用户在 Activity A 处于前台时点击“主页”按钮,然后从启动器重新调用应用程序,它会经历与场景 1 中相同的生命周期。即用户点击“主页”按钮。活动通过 onPause() 和 onStop()。用户再次启动应用程序,导致 Activity A 回到前台,再次经历与场景 1 相同的 onRestart()、onStart()、onResume() 序列。

据我所知,Activity 无法知道它是如何恢复的,它只知道它正在重新进入视野。事实上,我有一种感觉,在 Android 中并没有真正意义上的“应用程序”概念——从某种意义上说,它只有一个入口和出口点。

【问题讨论】:

  • 啊。实际上,我正在尝试跟踪应用程序启动的数量 - 但到目前为止还没有找到一种方法来区分不同的 onRestart() 场景。
  • 请记住,除了使用主页按钮之外,还有其他情况会恢复活动。当用户接到电话,系统杀死你的应用程序,然后恢复它时,它是一个新的应用程序启动吗?我认为跟踪应用程序中的交互会更好,而不是“启动”,但这是定义的。
  • 是的,我知道这些其他简历场景。即使我最终选择的方法(“singleTask”)也会在您切换任务时注册一个额外的“启动” - 例如拨打或接听电话。这意味着我会多算一点,但它似乎比通过增加 onCreate 或 really 在所有 onResume() 调用上过度计数来减少计数要好。

标签: android


【解决方案1】:

在场景 2 中,您的 Activity 将收到一个 onNewIntent 调用,并将启动器意图传递给它。

【讨论】:

  • 根据文档,onNewIntent 仅在某些启动模式下调用 - “singleTask”和“singleTop”。我只设法让它为“singleTask”工作,但是,文档不推荐这种启动模式。
  • 这种方法对我来说似乎没问题。我确实必须将“入口点”活动标记为“singleTask”,尽管如此。谢谢!
【解决方案2】:

您可以捕获 Activity B 上的后退按钮按下并将一个额外的值传递给 Activity A。如果有额外的值,则该活动从按下 Activity B 恢复,如果没有额外的值,则 Activity 是从隐藏状态恢复。

【讨论】:

  • 我觉得我需要处理这两种情况(活动 B 返回结果“用户按下活动 B 上的返回按钮)。
【解决方案3】:

Acitivity A 是否可以使用 startActivityForResult() 启动 Activity B 并使用 onActivityResult() 来检测 Activity B 是否已完成?

【讨论】:

  • 我猜 onActivityResult() 会在所有其他回调完成后发生?正如我在上面所评论的,我实际上对计算应用程序启动很感兴趣,这就是我一直关注 onStart() 和 onResume() 的原因。我已经看到其他建议 onCreate() 的响应,但是从“主”屏幕启动时不会触发。如果有东西从 onActivityResult() 返回,我可以减少计数,但这看起来很笨拙 - 也许是不可避免的?
【解决方案4】:

所以对最初问题的直接回答可能是:不。通过图标从主屏幕启动 Activity 或从最近屏幕恢复它不能从它(重新)启动/恢复的意图中观察到。

根据您要达到的目标,有一些方法:

  1. @superfell 的建议:

检查您的活动是否调用了onNewIntent-方法,以确定它是否从启动器重新启动。作为先决条件,您需要在 Manifest 中将活动设置为 singleTask/singleTop launchMode:

android:launchMode="singleTask"

根据您要达到的目标,这可能就足够了!但另外,您可能必须处理用户按下后退按钮时发生的情况。默认行为是完成并销毁您的活动。因此,当从“最近”屏幕中选择它时,将启动它的全新副本。尽管onNewIntent不会被调用,但一切都将从头开始重建。如果您需要防止这种情况,您可以使用:

override fun onBackPressed() {
    moveTaskToBack(true)
}

最后,当您从自己发起的活动导航“返回”时,onNewIntent 也将不会被调用。如果您进一步需要区分恢复活动的原因,您可能希望使用startActivityForResult 开始第二个活动,以便在恢复时调用onActivityResult

  1. 启动器活动和额外意图

一种完全不同的方法是在您的清单中有一个“启动器”活动,它直接调用您的“主要”活动并自行完成。当调用你的主要活动时,你可以添加一个额外的意图,允许你的主要活动区分它是否是第一次启动的。由于额外的内容将出现在进一步的 onResumes 中,因此请确保在您第一次“使用”它时覆盖它:

override fun onResume() {
    super.onResume()
    val firstLaunch = intent.getBooleanExtra(FIRST_LAUNCH, false)
    intent.putExtra(FIRST_LAUNCH,  false)
    if (firstLaunch) {
      // do something
    }
}

当从“启动器”活动开始时:

intent.putExtra(FIRST_LAUNCH, true)
startActivity(intent)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-11
    • 2022-02-16
    • 2012-02-22
    • 1970-01-01
    相关资源
    最近更新 更多