Sev*_*ver 34 android android-lifecycle android-fragments android-activity
Google 在 Android 上弃用 fragment 的 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.
Run Code Online (Sandbox Code Playgroud)
所以我尝试以推荐的方式制作它,但我只能在 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)
}
Run Code Online (Sandbox Code Playgroud)
上面的代码有什么问题?
更新 1:看起来我忘记使用 hostActivity.lifecycle.currentState 并检查片段的生命周期而不是活动生命周期。
更新 2:当您从一个到另一个单击后退按钮时,Google 建议的方法不适用于 1 个主机活动和 2 个片段,导致从未调用过 onAttach,但调用了 onActivityCreated。
Emb*_*ous 29
根据此处的变更日志
该
onActivityCreated()方法现已弃用。接触片段视图的代码应该在onViewCreated()(紧接在 之前调用onActivityCreated())完成,其他初始化代码应该在onCreate(). 要在活动onCreate()完成时专门接收回调,LifeCycleObserver应在活动的生命周期中注册onAttach(),并在onCreate()收到回调后将其删除。
你可以在你的片段类中做这样的事情:
class MyFragment : Fragment(), LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun onCreated(){
activity?.lifecycle?.removeObserver(this)
}
override fun onAttach(context: Context) {
super.onAttach(context)
activity?.lifecycle?.addObserver(this)
}
}
Run Code Online (Sandbox Code Playgroud)
小智 7
您可以将 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)
}
}
Run Code Online (Sandbox Code Playgroud)
更多细节
https://developer.android.com/topic/libraries/architecture/lifecycle#lc
我用下一种方式做到了:
class MyActivityObserver(
private val update: () -> Unit
) : DefaultLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {
super.onCreate(owner)
owner.lifecycle.removeObserver(this)
update()
}
}
Run Code Online (Sandbox Code Playgroud)
并在 onAttach(或其他生命周期方法)片段中使用它,例如:
myActivity.lifecycle.addObserver(MyActivityObserver {
myOnActivityCreated()
})
Run Code Online (Sandbox Code Playgroud)
2023 年 9 月 17 日更新
launchWhenCreated已被弃用(请参阅详细的博客文章),因为它会导致资源浪费(不是在这种情况下,但在本例中我们没有连续订阅任何资源)下面的代码launchWhenCreated可以在以下代码的帮助下复制repeatOnLifecycle
override fun onAttach(context: Context) {
super.onAttach(context)
requireActivity().lifecycleScope.launch {
requireActivity().lifecycle.repeatOnLifecycle(Lifecycle.State.CREATED) {
setupActionbar()
}
}
}
Run Code Online (Sandbox Code Playgroud)
How does it work? lifecycleScope.launch launches a scope with suspend block in the activity lifecycle. This scope is required as repeatOnLifecycle is a suspending function which can only be called inside suspend block. Here repeatOnLifecycle automatically stops the job when lifecycle goes out of the State.CREATED and then relaunches it when it comes back to the State.CREATED
Original post
The best way to solve the issue is to use lifecycleScope which is present in the activity lifecycle. Below is the code snippet
override fun onAttach(context: Context) {
super.onAttach(context)
activity?.lifecycleScope?.launchWhenCreated {
setupActionbar()
}
}
Run Code Online (Sandbox Code Playgroud)
How does it work? launchWhenXxx runs the launch block when it automatically reaches the specified state(in this case it is Created) and if the lifecycle goes to the destroyed state it cancels the launched coroutine automatically. Internally lifecycleScope uses Dispatchers.Main.immediate and hence there is no penalty for thread switching
Pros of this approach are the following:
You have to latest activity and fragment dependencies to use lifecycleScope attached to the lifecycle
| 归档时间: |
|
| 查看次数: |
15696 次 |
| 最近记录: |