Użyj viewLifecycleOwner jako LifecycleOwner


17

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

W moim fragmencie mam instancję StudentsViewModel, która została zainicjowana w onViewCreated(...).

W, StudentsViewModel, studentsto LiveData:

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

Powrót do MyFragmentw funkcji updateStudentList()otrzymuję błąd kompilatora skarży się thisparametr minąłem się, by .observe(this, Observer{...})toUse viewLifecycleOwner as the LifecycleOwner

Dlaczego dostaję ten błąd? Jak się tego pozbyć?

Odpowiedzi:


32

Dlaczego dostaję ten błąd?

Lint zaleca stosowanie cyklu życia widoków fragmentu ( viewLifecycleOwner) zamiast cyklu życia samego fragmentu ( this). Ian Lake i Jeremy Woods z Google zastanawiają się nad różnicą w ramach prezentacji na szczycie programistów Androida , a Ibrahim Yilmaz opisuje różnice w tym średnim poście W skrócie:

  • viewLifecycleOwnerjest powiązany z tym, kiedy fragment ma (i traci) swój interfejs użytkownika ( onCreateView(),onDestroyView() )

  • thisjest powiązany z ogólnym cyklem życia fragmentu ( onCreate(), onDestroy()), który może być znacznie dłuższy

Jak się tego pozbyć?

Zastąpić:

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

z:

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

W twoim obecnym kodzie, jeśli onDestroyView()jest wywoływany, ale onDestroy()nie jest, będziesz nadal obserwować LiveData, być może zawieszanie się, gdy spróbujesz wypełnić nieistniejące RecyclerView. Używając viewLifecycleOwner, unikasz tego ryzyka.


6
Pamiętaj, że nadal powinieneś używać „tego” w przypadku DialogFragment (i prawdopodobnie każdego fragmentu, który nie zwraca widoku dla onCreateView. W przeciwnym razie otrzymasz wyjątek:IllegalStateException: Can't access the Fragment View's LifecycleOwner when getView() is null i.e., before onCreateView() or after onDestroyView()
programista Androida

@androiddeveloper Nadal możesz używać lifeCycleOwner w programie onViewCreated i później?
jontro

@ jontro Jestem pewien, że możesz. Spróbuj i daj mi znać :)
programista Androida

@androiddeveloper wydaje się działać dobrze!
jontro

1

Zamiast thisużywać viewLifecycleOwnerdo obserwacjiLiveData

viewModel.students.observe(viewLifecycleOwner, Observer {
    //TODO: populate recycler view
})
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.