android-fragments onActivityCreated已过时,如何正确使用LifecycleObserver?

njthzxwz  于 2022-11-14  发布在  Android
关注(0)|答案(4)|浏览(482)

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:姓名首字母缩写.

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,并检查了片段的生命周期,而不是Activities生命周期。
更新2:Google建议的方法不适用于1个主机活动和2个片段,当您单击返回按钮从一个片段切换到另一个片段时,原因是从未调用onAttach,但调用了onActivityCreated。

xvw2m8pv

xvw2m8pv1#

根据此处的更改日志
onActivityCreated()方法现在已被弃用。涉及片段视图的代码应在onViewCreated()中完成(在onActivityCreated()之前立即调用)和其他初始化代码应位于onCreate()中。要在Activity的onCreate()完成时接收回调,应在Activity的生命周期中的onAttach()中注册LifeCycleObserver,并且一旦接收到onCreate()回调就将其移除。
你可以在fragment类中做类似这样的事情:

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()
    }
}
v09wglhw

v09wglhw2#

我所需要的只是onActivityCreated(...),因此我实现了一个观察器:

  • 自动删除自身(使用.removeObserver(...))。
  • 然后调用通过回调(update())。

我在旁边道:

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()
})
e0bqpujr

e0bqpujr3#

您可以将Lifecycle.State视为图形中的节点,将Lifecycle.Event视为这些节点之间的边。
这样你就永远不会到达State.上创建你的ON_CREATE函数。

解决方案

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

ef1yzkbh

ef1yzkbh4#

解决这个问题的最好方法是使用lifecycleScope,它出现在活动生命周期中。

override fun onAttach(context: Context) {
    super.onAttach(context)
    activity?.lifecycleScope?.launchWhenCreated {
        setupActionbar()
    }
}

launchWhenXxx会在启动块自动到达指定状态时运行启动块(在本例中为Created),如果生命周期进入销毁状态,它会自动取消启动的协程。lifecycleScope在内部使用Dispatchers.Main.immediate,因此不会出现线程切换的损失
这种方法的优点如下:
1.您不必手动维护观察器的注册和取消注册
1.无需覆盖两个生命周期方法
您必须拥有最新的Activity和片段依赖项,才能使用附加到生命周期的生命周期范围

相关问题