我想创建一个能够设置计时器并处理隐式意图 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 。
更令人困惑的是,onCreate
和onStart
显然看到了不同的意图。
从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
的两个不同实例:
MainActivity
的实例,并在其上调用onCreate()
/ onStart()
SET_ALARM
隐式Intent
MainActivity
的第二个实例,并将该任务带到前台MainActivity
调用onCreate()
的第二个实例,然后在其中使用finish()
MainActivity
的第一个实例),所以该 Activity 被带回前台,并在其上调用onStart()
我无法专门与助手交谈,因为我完全避免了它。但是,如果您希望“助理”启动的 Activity 位于单独的任务中,而不希望将任何现有任务置于前台,则您需要为此在 list 中做一些事情。我的出发点是针对不同的场景进行单独的 Activity ,然后在
android:taskAffinity
Activity 上使用SET_ALARM
将其路由到单独的任务。
关于android - Android-onCreate中的finish()行为不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60028765/