onActivityCreated 已弃用,如何正确使用 LifecycleObserver?
onActivityCreated is deprecated, how to properly use LifecycleObserver?
Google 在 Android 上弃用片段的 onActivityCreated() 并推荐使用 LifeCycleObserver:
To get a callback specifically when a Fragment activity's
* {@link Activity#onCreate(Bundle)} is called, register a
* {@link androidx.lifecycle.LifecycleObserver} on the Activity's
* {@link Lifecycle} in {@link #onAttach(Context)}, removing it when it receives the
* {@link Lifecycle.State#CREATED} callback.
所以我尝试按照推荐的方式制作它,但我在 Logcat 中只能观察到的状态只是 State: INITIALIZED。
private lateinit var lifecycleObserver: LifecycleObserver
override fun onAttach(context: Context) {
super.onAttach(context)
hostActivity = context as HostActivity
lifecycleObserver = object : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun onCreate() {
Logger.tag("SOME-TAG")d("State: ${lifecycle.currentState}")
if(lifecycle.currentState.isAtLeast(Lifecycle.State.CREATED)) {
Logger.tag("SOME-TAG").d("CREATED")
hostActivity.lifecycle.removeObserver(lifecycleObserver)
}
}
}
hostActivity.lifecycle.addObserver(lifecycleObserver)
}
上面的代码有什么问题?
更新 1:看来我忘记使用 hostActivity.lifecycle.currentState 并检查了片段的生命周期而不是活动生命周期。
更新 2:Google 方法建议不适用于
1 个主机 activity 和 2 个片段,当您单击后退按钮从一个到另一个时,导致 onAttach 从未被调用,但 onActivityCreated 被调用。
您可以将 Lifecycle.State 视为图中的节点,将 Lifecycle.Event 视为这些节点之间的边。
所以你永远不会到达你的 ON_CREATE 函数的 State.Created。
解决方案
class YourFragment : Fragment(), LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun onCreated(){
Log.i("tag","reached the State.Created")
}
override fun onAttach(context: Context) {
super.onAttach(context)
lifecycle.addObserver(this)
}
override fun onDetach() {
super.onDetach()
lifecycle.removeObserver(this)
}
}
更多详情
https://developer.android.com/topic/libraries/architecture/lifecycle#lc
根据更新日志 here
The onActivityCreated()
method is now deprecated. Code touching the
fragment's view should be done in onViewCreated()
(which is called
immediately before onActivityCreated()
) and other initialization code
should be in onCreate()
. To receive a callback specifically when the
activity's onCreate()
is complete, a LifeCycleObserver
should be
registered on the activity's Lifecycle in onAttach()
, and removed once
the onCreate()
callback is received.
你可以在你的片段中做这样的事情 class:
class MyFragment : Fragment(), LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun onCreated() {
// ... Your Logic goes here ...
}
override fun onAttach(context: Context) {
super.onAttach(context)
activity?.lifecycle?.addObserver(this)
}
override fun onDetach() {
activity?.lifecycle?.removeObserver(this)
super.onDetach()
}
}
我用下面的方法做了:
class MyActivityObserver(
private val update: () -> Unit
) : DefaultLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {
super.onCreate(owner)
owner.lifecycle.removeObserver(this)
update()
}
}
并在片段 onAttach(或其他生命周期方法)中使用它,例如:
myActivity.lifecycle.addObserver(MyActivityObserver {
myOnActivityCreated()
})
解决该问题的最佳方法是使用 lifecycleScope
,它存在于 activity 生命周期中。下面是代码片段
override fun onAttach(context: Context) {
super.onAttach(context)
activity?.lifecycleScope?.launchWhenCreated {
setupActionbar()
}
}
它是如何工作的? launchWhenXxx
当启动块自动达到指定状态(在本例中为已创建)时运行启动块,如果生命周期进入销毁状态,它会自动取消启动的协程。 内部lifecycleScope
使用Dispatchers.Main.immediate
因此没有线程切换的惩罚
这种方法的优点如下:
- 您不必手动维护观察者的注册和注销
- 无需覆盖两个生命周期方法
您必须拥有最新的 activity 和片段依赖项才能使用附加到生命周期的生命周期范围
Google 在 Android 上弃用片段的 onActivityCreated() 并推荐使用 LifeCycleObserver:
To get a callback specifically when a Fragment activity's
* {@link Activity#onCreate(Bundle)} is called, register a
* {@link androidx.lifecycle.LifecycleObserver} on the Activity's
* {@link Lifecycle} in {@link #onAttach(Context)}, removing it when it receives the
* {@link Lifecycle.State#CREATED} callback.
所以我尝试按照推荐的方式制作它,但我在 Logcat 中只能观察到的状态只是 State: INITIALIZED。
private lateinit var lifecycleObserver: LifecycleObserver
override fun onAttach(context: Context) {
super.onAttach(context)
hostActivity = context as HostActivity
lifecycleObserver = object : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun onCreate() {
Logger.tag("SOME-TAG")d("State: ${lifecycle.currentState}")
if(lifecycle.currentState.isAtLeast(Lifecycle.State.CREATED)) {
Logger.tag("SOME-TAG").d("CREATED")
hostActivity.lifecycle.removeObserver(lifecycleObserver)
}
}
}
hostActivity.lifecycle.addObserver(lifecycleObserver)
}
上面的代码有什么问题?
更新 1:看来我忘记使用 hostActivity.lifecycle.currentState 并检查了片段的生命周期而不是活动生命周期。
更新 2:Google 方法建议不适用于 1 个主机 activity 和 2 个片段,当您单击后退按钮从一个到另一个时,导致 onAttach 从未被调用,但 onActivityCreated 被调用。
您可以将 Lifecycle.State 视为图中的节点,将 Lifecycle.Event 视为这些节点之间的边。
所以你永远不会到达你的 ON_CREATE 函数的 State.Created。
解决方案
class YourFragment : Fragment(), LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun onCreated(){
Log.i("tag","reached the State.Created")
}
override fun onAttach(context: Context) {
super.onAttach(context)
lifecycle.addObserver(this)
}
override fun onDetach() {
super.onDetach()
lifecycle.removeObserver(this)
}
}
更多详情
https://developer.android.com/topic/libraries/architecture/lifecycle#lc
根据更新日志 here
The
onActivityCreated()
method is now deprecated. Code touching the fragment's view should be done inonViewCreated()
(which is called immediately beforeonActivityCreated()
) and other initialization code should be inonCreate()
. To receive a callback specifically when the activity'sonCreate()
is complete, aLifeCycleObserver
should be registered on the activity's Lifecycle inonAttach()
, and removed once theonCreate()
callback is received.
你可以在你的片段中做这样的事情 class:
class MyFragment : Fragment(), LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun onCreated() {
// ... Your Logic goes here ...
}
override fun onAttach(context: Context) {
super.onAttach(context)
activity?.lifecycle?.addObserver(this)
}
override fun onDetach() {
activity?.lifecycle?.removeObserver(this)
super.onDetach()
}
}
我用下面的方法做了:
class MyActivityObserver(
private val update: () -> Unit
) : DefaultLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {
super.onCreate(owner)
owner.lifecycle.removeObserver(this)
update()
}
}
并在片段 onAttach(或其他生命周期方法)中使用它,例如:
myActivity.lifecycle.addObserver(MyActivityObserver {
myOnActivityCreated()
})
解决该问题的最佳方法是使用 lifecycleScope
,它存在于 activity 生命周期中。下面是代码片段
override fun onAttach(context: Context) {
super.onAttach(context)
activity?.lifecycleScope?.launchWhenCreated {
setupActionbar()
}
}
它是如何工作的? launchWhenXxx
当启动块自动达到指定状态(在本例中为已创建)时运行启动块,如果生命周期进入销毁状态,它会自动取消启动的协程。 内部lifecycleScope
使用Dispatchers.Main.immediate
因此没有线程切换的惩罚
这种方法的优点如下:
- 您不必手动维护观察者的注册和注销
- 无需覆盖两个生命周期方法
您必须拥有最新的 activity 和片段依赖项才能使用附加到生命周期的生命周期范围