Android-onCreate中的finish()行为不一致

Android-onCreate中的finish()行为不一致,android,kotlin,android-intent,android-lifecycle,Android,Kotlin,Android Intent,Android Lifecycle,我想创建一个Android应用程序,它能够设置计时器,并处理隐式意图。这也将允许它对谷歌助手的“设置计时器”命令做出反应 收到此特殊目的后,我希望应用程序在不显示活动的情况下设置计时器(以表示尊重) 如果在我使用GoogleAssistant设置计时器时应用程序没有启动,它会按预期工作:活动不会显示,但设置计时器的代码会执行 但是,如果我使用launcher启动我的活动,然后使用home按钮返回主屏幕(即,该活动仍然可以在最近找到),则该行为是错误的。显示活动时,调用onStart()方法(即使

我想创建一个Android应用程序,它能够设置计时器,并处理隐式意图。这也将允许它对谷歌助手的“设置计时器”命令做出反应

收到此特殊目的后,我希望应用程序在不显示活动的情况下设置计时器(以表示尊重)

如果在我使用GoogleAssistant设置计时器时应用程序没有启动,它会按预期工作:活动不会显示,但设置计时器的代码会执行

但是,如果我使用launcher启动我的活动,然后使用home按钮返回主屏幕(即,该活动仍然可以在最近找到),则该行为是错误的。显示活动时,调用
onStart()
方法(即使我从
onCreate
调用
finish()

据我所知,如果我从
onCreate
调用
finish()
,则不应调用其他生命周期回调,并且不应显示活动

更令人困惑的是,显然
onCreate
onStart
请参见不同的意图

AndroidManifest.xml


MainActivity.kt

class MainActivity : AppCompatActivity() {
    companion object {
        const val TAG = "MainActivity"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        Log.d(TAG, "onCreate called")
        super.onCreate(savedInstanceState)
        logIntent()

        if (intent.action == AlarmClock.ACTION_SET_TIMER) {
            Log.d(TAG, "Timer intent received, closing")
            // Do something useful here
            setResult(Activity.RESULT_OK)
            finish()
            return
        }

        setContentView(R.layout.activity_main)
    }

    override fun onStart() {
        Log.d(TAG,"onStart called")
        super.onStart()
        logIntent()
    }

    private fun logIntent() {
        Log.d(TAG, "Intent action ${intent.action}")
        Log.d(TAG, "Intent flags ${intent.flags.toString(16)}")

        intent.extras?.keySet()?.forEach {
            Log.d(TAG, "Intent extra $it = ${intent.extras?.get(it)}")
        }
    }
}
情景1 应用程序未启动,请使用谷歌助手设置计时器。 这里一切正常

情景2 应用程序由启动器启动,按下Home按钮,然后使用GoogleAssistant设置计时器。 使用launcher启动应用程序,外观与预期一致:

2020-02-02 18:24:30.052 22269-22269/com.example.testlifycycle D/MainActivity: onCreate called
2020-02-02 18:24:30.055 22269-22269/com.example.testlifycycle D/MainActivity: Intent action android.intent.action.MAIN
2020-02-02 18:24:30.055 22269-22269/com.example.testlifycycle D/MainActivity: Intent flags 10200000
2020-02-02 18:24:30.055 22269-22269/com.example.testlifycycle D/MainActivity: Intent extra profile = 0
2020-02-02 18:24:30.158 22269-22269/com.example.testlifycycle D/MainActivity: onStart called
2020-02-02 18:24:30.158 22269-22269/com.example.testlifycycle D/MainActivity: Intent action android.intent.action.MAIN
2020-02-02 18:24:30.158 22269-22269/com.example.testlifycycle D/MainActivity: Intent flags 10200000
2020-02-02 18:24:30.158 22269-22269/com.example.testlifycycle D/MainActivity: Intent extra profile = 0
按home按钮,然后使用Google助手:

2020-02-02 18:26:21.398 23158-23158/com.example.testlifycycle D/MainActivity: onCreate called
2020-02-02 18:26:21.402 23158-23158/com.example.testlifycycle D/MainActivity: Intent action android.intent.action.SET_TIMER
2020-02-02 18:26:21.402 23158-23158/com.example.testlifycycle D/MainActivity: Intent flags 10400000
2020-02-02 18:26:21.402 23158-23158/com.example.testlifycycle D/MainActivity: Intent extra android.intent.extra.alarm.SKIP_UI = true
2020-02-02 18:26:21.402 23158-23158/com.example.testlifycycle D/MainActivity: Intent extra com.google.android.apps.gsa.shared.util.starter.IntentStarter.ERROR_TOAST_ID = 2131951799
2020-02-02 18:26:21.403 23158-23158/com.example.testlifycycle D/MainActivity: Intent extra android.intent.extra.REFERRER_NAME = android-app://com.google.android.googlequicksearchbox/https/www.google.com
2020-02-02 18:26:21.403 23158-23158/com.example.testlifycycle D/MainActivity: Intent extra android.intent.extra.alarm.LENGTH = 60
2020-02-02 18:26:21.403 23158-23158/com.example.testlifycycle D/MainActivity: Intent extra KEY_HANDOVER_THROUGH_VELVET = true
2020-02-02 18:26:21.403 23158-23158/com.example.testlifycycle D/MainActivity: Timer intent received, closing
2020-02-02 18:26:21.446 23158-23158/com.example.testlifycycle D/MainActivity: onStart called
2020-02-02 18:26:21.446 23158-23158/com.example.testlifycycle D/MainActivity: Intent action android.intent.action.MAIN
2020-02-02 18:26:21.446 23158-23158/com.example.testlifycycle D/MainActivity: Intent flags 10200000
2020-02-02 18:26:21.447 23158-23158/com.example.testlifycycle D/MainActivity: Intent extra profile = 0
我在这里看到的问题是:

  • 即使从
    onCreate
    调用了
    finsh
    ,也会调用
    onStart
  • onStart
    使用操作
    MAIN
    记录意图,而
    onCreate
    记录(预期)
    SET\u计时器

  • 我想我可能对Android的意图/生命周期机制缺乏了解。我将非常感谢您对此事的帮助。

    您正在处理两个不同的
    MainActivity
    实例:

    • 点击启动器图标
    • Android创建了一个
      MainActivity
      的实例,并对其调用了
      onCreate()
      /
      onStart()
    • 你按回家
    • 你做了一些辅助动作,触发了
      SET\u报警
      implicit
      Intent
    • Android在现有任务中创建第二个
      MainActivity
      实例,并将该任务置于前台
    • onCreate()
      调用
      MainActivity
      的第二个实例,然后在那里调用该实例
    • 由于您的任务位于前台,并且该任务中还有另一个活动(第一个实例是
      MainActivity
      ),因此该活动将返回前台,并对其调用
      onStart()

    我不能具体地和助手说话,因为我完全回避。但是,如果希望助手启动的活动位于单独的任务中,并且不将任何现有任务带到前台,则需要在清单中为此做一些工作。我的出发点是为不同的场景设置不同的活动,然后在
    SET\u ALARM
    活动上使用
    android:taskAffinity
    将其路由到单独的任务。

    Hi,您是否在清单中传递了类似
    android:launchMode
    的任何标志?调用finish()时仍将调用onStart()。您的完成请求在主线程上排队,直到您的应用程序处于启动状态时才会执行。(这种行为也没有任何问题,这不是你要寻找的答案)。@Blundell这一IMO反驳了:>你可以从这个函数中调用finish(),在这种情况下,onCreate(Bundle)之后将立即调用onDestroy(),而不需要任何其他活动生命周期(onStart()、onResume()、onPause()等)执行。@Mustansir,不,我不知道t@Nu-hin看来onStart调用是最近活动的“恢复”,这就是为什么它有主标志的原因。是的,我的解释错了!这正是我所想的。使用单独的意图过滤器将其拆分为两个活动+1但如果未设置
    EXTRA\u SKIP\u UI
    ,则会发生什么情况,因此仍然需要显示该活动?这是否意味着有两个具有(几乎)相同UI的活动?@Nu-hin:您可以尝试将
    用于
    SET\u ALARM
    操作和
    taskAffinity
    设置,尽管我从未尝试过这种组合。或者,如果需要真正的用户界面,您可以让专用的
    SET\u报警
    活动只需启动
    main活动
    (然后是自己的
    finish()
    调用以摆脱自身)。或者,您可以让
    设置\u报警
    活动成为
    main活动
    的子类。我怀疑还有其他选项,但我想到了三个。@commonware我最终创建了一个空活动,没有布局和
    taskafinity
    set,正如您所建议的那样。这就解决了问题,非常感谢。
    2020-02-02 18:26:21.398 23158-23158/com.example.testlifycycle D/MainActivity: onCreate called
    2020-02-02 18:26:21.402 23158-23158/com.example.testlifycycle D/MainActivity: Intent action android.intent.action.SET_TIMER
    2020-02-02 18:26:21.402 23158-23158/com.example.testlifycycle D/MainActivity: Intent flags 10400000
    2020-02-02 18:26:21.402 23158-23158/com.example.testlifycycle D/MainActivity: Intent extra android.intent.extra.alarm.SKIP_UI = true
    2020-02-02 18:26:21.402 23158-23158/com.example.testlifycycle D/MainActivity: Intent extra com.google.android.apps.gsa.shared.util.starter.IntentStarter.ERROR_TOAST_ID = 2131951799
    2020-02-02 18:26:21.403 23158-23158/com.example.testlifycycle D/MainActivity: Intent extra android.intent.extra.REFERRER_NAME = android-app://com.google.android.googlequicksearchbox/https/www.google.com
    2020-02-02 18:26:21.403 23158-23158/com.example.testlifycycle D/MainActivity: Intent extra android.intent.extra.alarm.LENGTH = 60
    2020-02-02 18:26:21.403 23158-23158/com.example.testlifycycle D/MainActivity: Intent extra KEY_HANDOVER_THROUGH_VELVET = true
    2020-02-02 18:26:21.403 23158-23158/com.example.testlifycycle D/MainActivity: Timer intent received, closing
    2020-02-02 18:26:21.446 23158-23158/com.example.testlifycycle D/MainActivity: onStart called
    2020-02-02 18:26:21.446 23158-23158/com.example.testlifycycle D/MainActivity: Intent action android.intent.action.MAIN
    2020-02-02 18:26:21.446 23158-23158/com.example.testlifycycle D/MainActivity: Intent flags 10200000
    2020-02-02 18:26:21.447 23158-23158/com.example.testlifycycle D/MainActivity: Intent extra profile = 0