使用viewLifecycleOwner作为LifecycleOwner


17

我有一个片段:

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(...)

在中StudentsViewModelstudentsLiveData

class StudentsViewModel : ViewModel() {
    val students = liveData(Dispatchers.IO) {
          ...
    }
}

返回MyFragment,在功能上updateStudentList(),我得到编译器错误抱怨this我中传递的参数.observe(this, Observer{...})Use viewLifecycleOwner as the LifecycleOwner

为什么会出现此错误?如何摆脱它?

Answers:


31

为什么会出现此错误?

Lint建议您使用片段视图viewLifecycleOwner的生命周期(),而不要使用片段本身的生命周期(this)。Google的Ian Lake和Jeremy Woods作为Android开发者峰会演讲的一部分,探讨了这一差异,而Ibrahim Yilmaz 概括了此Medium帖子中的差异:

  • viewLifecycleOwner是依赖于当所述片段具有(且失去)它的UI( ,)onCreateView()onDestroyView()

  • this是联系在一起的片段的整体的生命周期(onCreate()onDestroy()),其可以是基本上更长

如何摆脱它?

更换:

viewModel.students.observe(this, Observer {
        //TODO: populate recycler view
    })

与:

viewModel.students.observe(viewLifecycleOwner, Observer {
        //TODO: populate recycler view
    })

在当前代码中,如果onDestroyView()调用了,但未调用,onDestroy()则将继续观察LiveData,当您尝试填充不存在的时可能会崩溃RecyclerView。通过使用viewLifecycleOwner,您可以避免这种风险。


6
请注意,在DialogFragment的情况下,您仍然应该使用“ this”(并且可能每个片段都不会返回onCreateView的视图。否则,您将得到一个例外:IllegalStateException: Can't access the Fragment View's LifecycleOwner when getView() is null i.e., before onCreateView() or after onDestroyView()
android开发人员

@androiddeveloper您仍然可以在onViewCreated及更高版本中使用lifeCycleOwner吗?
jontro

@jontro肯定可以。试试看,让我知道:)
android开发人员

@androiddeveloper似乎工作正常!
jontro

1

而不是this使用viewLifecycleOwner观察LiveData

viewModel.students.observe(viewLifecycleOwner, Observer {
    //TODO: populate recycler view
})
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.