Verwenden Sie viewLifecycleOwner als LifecycleOwner

17

Ich habe ein Fragment:

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

In meinem Fragment habe ich eine Instanz von StudentsViewModel, die in initiiert wird onViewCreated(...).

In StudentsViewModel, studentsist ein LiveData:

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

Zurück zu MyFragment, in der Funktion updateStudentList()erhalte ich einen Compilerfehler, der den thisParameter beschwert, den ich an .observe(this, Observer{...})diesen übergeben habeUse viewLifecycleOwner as the LifecycleOwner

Warum bekomme ich diesen Fehler? Wie kann man es loswerden?

user842225
quelle

Antworten:

33

Warum bekomme ich diesen Fehler?

Lint empfiehlt, dass Sie den Lebenszyklus der Ansichten des Fragments ( viewLifecycleOwner) anstelle des Lebenszyklus des Fragments selbst ( this) verwenden. Ian Lake und Jeremy Woods von Google gehen im Rahmen dieser Präsentation zum Android Developer Summit auf den Unterschied ein, und Ibrahim Yilmaz behandelt die Unterschiede in diesem Medium-Beitrag auf den Punkt gebracht:

  • viewLifecycleOwnerist gebunden, wenn das Fragment seine Benutzeroberfläche hat (und verliert) ( onCreateView(), onDestroyView())

  • thisist an den gesamten Lebenszyklus des Fragments ( onCreate(), onDestroy()) gebunden, der wesentlich länger sein kann

Wie kann man es loswerden?

Ersetzen:

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

mit:

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

Wenn in Ihrem aktuellen Code onDestroyView()aufgerufen wird, dies aber onDestroy()nicht der LiveDataFall ist, werden Sie das weiterhin beobachten und möglicherweise abstürzen, wenn Sie versuchen, ein nicht vorhandenes zu füllen RecyclerView. Durch die Verwendung viewLifecycleOwnervermeiden Sie dieses Risiko.

CommonsWare
quelle
6
Beachten Sie, dass Sie "this" im Fall von DialogFragment weiterhin verwenden sollten (und wahrscheinlich jedes Fragment, das keine Ansicht für onCreateView zurückgibt. Andernfalls erhalten Sie eine Ausnahme:IllegalStateException: Can't access the Fragment View's LifecycleOwner when getView() is null i.e., before onCreateView() or after onDestroyView()
Android-Entwickler
@androiddeveloper Sie könnten lifeCycleOwner weiterhin in onViewCreated und höher verwenden?
30.
@jontro Ziemlich sicher, dass du kannst. Probieren Sie es aus und lassen Sie es mich wissen :)
Android-Entwickler
@androiddeveloper scheint gut zu funktionieren!
Jontro
1

Statt thisVerwendung viewLifecycleOwnerzu beobachtenLiveData

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