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因此没有线程切换的惩罚

这种方法的优点如下:

  1. 您不必手动维护观察者的注册和注销
  2. 无需覆盖两个生命周期方法

您必须拥有最新的 activity 和片段依赖项才能使用附加到生命周期的生命周期范围