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

标签 android kotlin android-intent android-lifecycle

我想创建一个能够设置计时器并处理隐式意图 AlarmClock.ACTION_SET_TIMER 的Android应用程序。这也将使其响应Google助手的“设置计时器为”命令。

收到此特殊意图后,我希望该应用设置计时器而不显示 Activity (尊重 AlarmClock.EXTRA_SKIP_UI )。

如果当我使用Google Assistant设置计时器时未启动该应用程序,则该应用程序将按预期工作:未显示 Activity ,但用于设置计时器的代码已执行。

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

the documentation了解,如果我从finish()调用onCreate,则不应调用其他生命周期回调,并且不应显示该 Activity 。

更令人困惑的是,onCreateonStart显然看到了不同的意图

AndroidManifest.xml:

<activity android:name="com.example.testlifecycle.MainActivity">
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>

  <intent-filter>
    <action android:name="android.intent.action.SET_TIMER" />
    <category android:name="android.intent.category.DEFAULT" />
  </intent-filter>
</activity>
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

应用程序未启动,请使用Google Assistant设置计时器。
2020-02-02 18:21:28.376 22269-22269/com.example.testlifycycle D/MainActivity: onCreate called
2020-02-02 18:21:28.408 22269-22269/com.example.testlifycycle D/MainActivity: Intent action android.intent.action.SET_TIMER
2020-02-02 18:21:28.409 22269-22269/com.example.testlifycycle D/MainActivity: Intent flags 10000000
2020-02-02 18:21:28.409 22269-22269/com.example.testlifycycle D/MainActivity: Intent extra android.intent.extra.alarm.SKIP_UI = true
2020-02-02 18:21:28.409 22269-22269/com.example.testlifycycle D/MainActivity: Intent extra com.google.android.apps.gsa.shared.util.starter.IntentStarter.ERROR_TOAST_ID = 2131951799
2020-02-02 18:21:28.410 22269-22269/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:21:28.410 22269-22269/com.example.testlifycycle D/MainActivity: Intent extra android.intent.extra.alarm.LENGTH = 3600
2020-02-02 18:21:28.410 22269-22269/com.example.testlifycycle D/MainActivity: Intent extra KEY_HANDOVER_THROUGH_VELVET = true
2020-02-02 18:21:28.410 22269-22269/com.example.testlifycycle D/MainActivity: Timer intent received, closing

在这里一切都按预期工作。

方案2

应用程序由启动器启动,按“主页”按钮,然后使用Google助手设置计时器。

使用启动器启动应用程序,外观与预期的一样:
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

按主页按钮,然后使用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

我在这里看到的问题:

即使从onStart调用了finsh,也会调用
  • onCreate
  • onStart记录具有 Action MAIN的意图,而onCreate记录(预期)SET_TIMER

  • 我想我可能对Android意图/生命周期机制缺乏了解。我将不胜感激。

    最佳答案

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

  • 您点击启动器图标
  • Android创建MainActivity的实例,并在其上调用onCreate() / onStart()
  • 您按首页
  • 您执行了一些Assistant-y事情,触发了SET_ALARM隐式Intent
  • Android在现有任务中创建MainActivity的第二个实例,并将该任务带到前台
  • 使用MainActivity调用onCreate()的第二个实例,然后在其中使用
  • 实例的finish()
  • 因为您的任务在前台,并且该任务中还有另一个 Activity (MainActivity的第一个实例),所以该 Activity 被带回前台,并在其上调用onStart()

  • 我无法专门与助手交谈,因为我完全避免了它。但是,如果您希望“助理”启动的 Activity 位于单独的任务中,而不希望将任何现有任务置于前台,则您需要为此在 list 中做一些事情。我的出发点是针对不同的场景进行单独的 Activity ,然后在android:taskAffinity Activity 上使用SET_ALARM将其路由到单独的任务。

    关于android - Android-onCreate中的finish()行为不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60028765/

    相关文章:

    android - POST alamofire 数组参数

    java - 如何检查 Cloud Firestore 集合是否存在? (查询快照)

    android - 将 android 应用程序链接到现有网站的数据库

    loops - 尽管 Kotlin 的 `Map` 不是 `Iterable` ,但它如何以及为什么可迭代?

    android - 如何找到使用 Intent MediaStore.ACTION_IMAGE_CAPTURE 拍摄的照片的方向?

    java - android 测试 HttpPost 字符串以进行调试

    android - Kotlin -IllegalArgumentException : Parameter specified as non-null is null

    Spring Data JDBC - Kotlin 支持 - 未找到类所需的属性

    android-intent - "No Activity found to handle Intent"在通过电子邮件发送数据时

    android - 用户在Kotlin中授予使用访问权限后,如何导航回我的应用程序