生命周期观察器与 Nexus 5 上的生命周期函数不一致
Lifecycle observer inconsistent with lifecycle functions on Nexus 5
我注意到 Nexus 5 设备在标准 Android 生命周期方法(onCreate
、onStart
等)和 LifecycleObserver attached to the AppCompatActivity 生命周期之间存在一些不一致的行为。
打开共享对话框然后再次关闭时出现此问题。
鉴于此 activity:
package gustavkarlsson.se.lifecycleerrordemo
import android.arch.lifecycle.Lifecycle.Event.*
import android.arch.lifecycle.LifecycleObserver
import android.arch.lifecycle.OnLifecycleEvent
import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
init {
lifecycle.addObserver(object : LifecycleObserver {
@OnLifecycleEvent(ON_CREATE)
fun logOnCreate() {
Log.i(TAG, "Observed: $ON_CREATE")
}
@OnLifecycleEvent(ON_START)
fun logOnStart() {
Log.i(TAG, "Observed: $ON_START")
}
@OnLifecycleEvent(ON_RESUME)
fun logOnResume() {
Log.i(TAG, "Observed: $ON_RESUME")
}
@OnLifecycleEvent(ON_PAUSE)
fun logOnPause() {
Log.i(TAG, "Observed: $ON_PAUSE")
}
@OnLifecycleEvent(ON_STOP)
fun logOnStop() {
Log.i(TAG, "Observed: $ON_STOP")
}
@OnLifecycleEvent(ON_DESTROY)
fun logOnDestroy() {
Log.i(TAG, "Observed: $ON_DESTROY")
}
})
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.i(TAG, "Ran onCreate")
email_button.setOnClickListener { openShareDialog() }
}
private fun openShareDialog() {
Intent(Intent.ACTION_SEND).run {
type = "message/rfc822"
putExtra(Intent.EXTRA_EMAIL, arrayOf("test@mail.com"))
putExtra(Intent.EXTRA_SUBJECT, "Subject")
putExtra(Intent.EXTRA_TEXT, "Text")
startActivity(Intent.createChooser(this, "Send Email"))
}
}
override fun onStart() {
super.onStart()
Log.i(TAG, "Ran onStart")
}
override fun onResume() {
super.onResume()
Log.i(TAG, "Ran onResume")
}
override fun onPause() {
super.onPause()
Log.i(TAG, "Ran onPause")
}
override fun onStop() {
super.onStop()
Log.i(TAG, "Ran onStop")
}
override fun onDestroy() {
super.onDestroy()
Log.i(TAG, "Ran onDestroy")
}
companion object {
private const val TAG = "MainActivity"
}
}
我希望从观察者和相应的生命周期方法中记录每个生命周期转换。
但是,当我单击按钮打开共享对话框然后再次将其关闭时,不同设备的行为不同。
Samsung Galaxy A3 的表现符合我的预期:
04-03 12:53:55.394 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onCreate
04-03 12:53:55.396 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_CREATE
04-03 12:53:55.398 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onStart
04-03 12:53:55.398 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_START
04-03 12:53:55.404 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onResume
04-03 12:53:55.404 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_RESUME
* Opened share menu *
04-03 12:54:02.431 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_PAUSE
04-03 12:54:02.432 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onPause
* Closed share menu *
04-03 12:54:07.635 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onResume
04-03 12:54:07.636 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_RESUME
Google Nexus 5 观察到 ON_STOP
和 ON_START
,即使 onStop
和 onStart
永远不会叫:
04-03 12:51:32.964 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onCreate
04-03 12:51:32.965 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_CREATE
04-03 12:51:32.977 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onStart
04-03 12:51:32.977 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_START
04-03 12:51:32.977 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onResume
04-03 12:51:32.977 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_RESUME
* Opened share menu *
04-03 12:51:42.676 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_PAUSE
04-03 12:51:42.676 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onPause
04-03 12:51:43.395 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_STOP
* Closed share menu *
04-03 12:51:47.791 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onResume
04-03 12:51:47.791 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_START
04-03 12:51:47.791 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_RESUME
我的问题是:为什么 Nexus 会观察事件,即使相应的生命周期方法从来没有 运行?这是错误还是我误解了生命周期?
版本:
com.android.tools.build:gradle:3.1.0
org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.31
com.android.support:support-v4:27.1.0
com.android.support:appcompat-v7:27.1.0
compileSdkVersion 27
targetSdkVersion 27
我已经上传了演示项目 here。
Lifecycle 库将 AppCompatActivity
和 Fragment
Lifecycle 对象标记为 CREATED
并在 onSaveInstanceState()
被调用时调度 ON_STOP
而无需等待调用onStop()
方法。这是图书馆的described in the documentation。
文档指出这样做是为了让观察者更容易避免在调用 onSaveInstanceState()
后做会改变 UI 状态的事情,因为如果Activity 或 Fragment 被停止并立即销毁。
您的代码没有任何登录 onSaveInstanceState()
,这就是您没有看到此方法调用被记录的原因。
注意。我假设您使用的是 Lifecycle 库的 1.0.0-rc2 或更高版本,该库于 2017 年 10 月 18 日发布(比您提出问题早几个月)。根据 release notes,此行为在该版本中发生了变化。
我注意到 Nexus 5 设备在标准 Android 生命周期方法(onCreate
、onStart
等)和 LifecycleObserver attached to the AppCompatActivity 生命周期之间存在一些不一致的行为。
打开共享对话框然后再次关闭时出现此问题。
鉴于此 activity:
package gustavkarlsson.se.lifecycleerrordemo
import android.arch.lifecycle.Lifecycle.Event.*
import android.arch.lifecycle.LifecycleObserver
import android.arch.lifecycle.OnLifecycleEvent
import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
init {
lifecycle.addObserver(object : LifecycleObserver {
@OnLifecycleEvent(ON_CREATE)
fun logOnCreate() {
Log.i(TAG, "Observed: $ON_CREATE")
}
@OnLifecycleEvent(ON_START)
fun logOnStart() {
Log.i(TAG, "Observed: $ON_START")
}
@OnLifecycleEvent(ON_RESUME)
fun logOnResume() {
Log.i(TAG, "Observed: $ON_RESUME")
}
@OnLifecycleEvent(ON_PAUSE)
fun logOnPause() {
Log.i(TAG, "Observed: $ON_PAUSE")
}
@OnLifecycleEvent(ON_STOP)
fun logOnStop() {
Log.i(TAG, "Observed: $ON_STOP")
}
@OnLifecycleEvent(ON_DESTROY)
fun logOnDestroy() {
Log.i(TAG, "Observed: $ON_DESTROY")
}
})
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.i(TAG, "Ran onCreate")
email_button.setOnClickListener { openShareDialog() }
}
private fun openShareDialog() {
Intent(Intent.ACTION_SEND).run {
type = "message/rfc822"
putExtra(Intent.EXTRA_EMAIL, arrayOf("test@mail.com"))
putExtra(Intent.EXTRA_SUBJECT, "Subject")
putExtra(Intent.EXTRA_TEXT, "Text")
startActivity(Intent.createChooser(this, "Send Email"))
}
}
override fun onStart() {
super.onStart()
Log.i(TAG, "Ran onStart")
}
override fun onResume() {
super.onResume()
Log.i(TAG, "Ran onResume")
}
override fun onPause() {
super.onPause()
Log.i(TAG, "Ran onPause")
}
override fun onStop() {
super.onStop()
Log.i(TAG, "Ran onStop")
}
override fun onDestroy() {
super.onDestroy()
Log.i(TAG, "Ran onDestroy")
}
companion object {
private const val TAG = "MainActivity"
}
}
我希望从观察者和相应的生命周期方法中记录每个生命周期转换。
但是,当我单击按钮打开共享对话框然后再次将其关闭时,不同设备的行为不同。
Samsung Galaxy A3 的表现符合我的预期:
04-03 12:53:55.394 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onCreate
04-03 12:53:55.396 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_CREATE
04-03 12:53:55.398 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onStart
04-03 12:53:55.398 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_START
04-03 12:53:55.404 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onResume
04-03 12:53:55.404 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_RESUME
* Opened share menu *
04-03 12:54:02.431 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_PAUSE
04-03 12:54:02.432 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onPause
* Closed share menu *
04-03 12:54:07.635 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onResume
04-03 12:54:07.636 30109-30109/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_RESUME
Google Nexus 5 观察到 ON_STOP
和 ON_START
,即使 onStop
和 onStart
永远不会叫:
04-03 12:51:32.964 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onCreate
04-03 12:51:32.965 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_CREATE
04-03 12:51:32.977 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onStart
04-03 12:51:32.977 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_START
04-03 12:51:32.977 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onResume
04-03 12:51:32.977 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_RESUME
* Opened share menu *
04-03 12:51:42.676 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_PAUSE
04-03 12:51:42.676 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onPause
04-03 12:51:43.395 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_STOP
* Closed share menu *
04-03 12:51:47.791 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Ran onResume
04-03 12:51:47.791 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_START
04-03 12:51:47.791 22062-22062/gustavkarlsson.se.lifecycleerrordemo I/MainActivity: Observed: ON_RESUME
我的问题是:为什么 Nexus 会观察事件,即使相应的生命周期方法从来没有 运行?这是错误还是我误解了生命周期?
版本:
com.android.tools.build:gradle:3.1.0
org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.31
com.android.support:support-v4:27.1.0
com.android.support:appcompat-v7:27.1.0
compileSdkVersion 27
targetSdkVersion 27
我已经上传了演示项目 here。
Lifecycle 库将 AppCompatActivity
和 Fragment
Lifecycle 对象标记为 CREATED
并在 onSaveInstanceState()
被调用时调度 ON_STOP
而无需等待调用onStop()
方法。这是图书馆的described in the documentation。
文档指出这样做是为了让观察者更容易避免在调用 onSaveInstanceState()
后做会改变 UI 状态的事情,因为如果Activity 或 Fragment 被停止并立即销毁。
您的代码没有任何登录 onSaveInstanceState()
,这就是您没有看到此方法调用被记录的原因。
注意。我假设您使用的是 Lifecycle 库的 1.0.0-rc2 或更高版本,该库于 2017 年 10 月 18 日发布(比您提出问题早几个月)。根据 release notes,此行为在该版本中发生了变化。