我有一个片段:
class MyFragment : BaseFragment() {
// my StudentsViewModel instance
lateinit var viewModel: StudentsViewModel
override fun onCreateView(...){
...
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProviders.of(this).get(StudentsViewModel::class.java)
updateStudentList()
}
fun updateStudentList() {
// Compiler error on 'this': Use viewLifecycleOwner as the LifecycleOwner
viewModel.students.observe(this, Observer {
//TODO: populate recycler view
})
}
}
在我的片段中,我有一个StudentsViewModel的示例,它在onViewCreated(...)
中启动。
在,StudentsViewModel
、students
是一个LiveData
:
class StudentsViewModel : ViewModel() {
val students = liveData(Dispatchers.IO) {
...
}
}
回到MyFragment
,在函数updateStudentList()
中,我收到编译器错误,抱怨我传递给.observe(this, Observer{...})
的this
参数Use viewLifecycleOwner as the LifecycleOwner
为什么我得到这个错误?如何摆脱它?
4条答案
按热度按时间nsc4cvqm1#
为什么会出现此错误?
Lint建议您使用片段视图的生命周期(
viewLifecycleOwner
),而不是片段本身的生命周期(this
)。Google的Ian Lake和Jeremy Woods在this Android Developer Summit presentation中讨论了这一差异,Ibrahim Yilmaz在this Medium post中讨论了这一差异。viewLifecycleOwner
绑定到片段拥有(和丢失)其UI的时间(onCreateView()
,onDestroyView()
)this
与片段的整个生命周期(onCreate()
,onDestroy()
)相关联,该生命周期可能会长得多如何摆脱它?
替换:
与:
在您当前的代码中,如果调用了
onDestroyView()
,但没有调用onDestroy()
,您将继续观察LiveData
,当您尝试填充不存在的RecyclerView
时,可能会崩溃。通过使用viewLifecycleOwner
,您可以避免这种风险。jfgube3f2#
viewLifeCycleOwner是代表Fragment的View生命周期的LifecycleOwner。在大多数情况下,这反映Fragment本身的生命周期,但对于分离的Fragment,Fragment的生命周期可能比View本身的生命周期长得多。
当用户从片段导航离开时,即使片段本身没有被破坏,片段视图也会被破坏。这实际上创建了两个生命周期,片段的生命周期和片段视图的生命周期。引用片段的生命周期而不是片段视图的生命周期可能会在更新片段视图时导致微妙的错误。
qfe3c7zg3#
用
viewLifecycleOwner
代替this
来观察LiveData
uplii1fm4#
队长明显的说到这里,有用的也可能是这个: