Usa viewLifecycleOwner come LifecycleOwner


17

Ho un frammento:

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

Nel mio frammento, ho un'istanza di StudentsViewModel che viene avviata in onViewCreated(...).

In, StudentsViewModel, studentsè una LiveData:

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

Tornando a MyFragment, nella funzione updateStudentList()ricevo un errore del compilatore che si lamenta del thisparametro passato a .observe(this, Observer{...})quelloUse viewLifecycleOwner as the LifecycleOwner

Perché visualizzo questo errore? Come sbarazzarsene?

Risposte:


34

Perché visualizzo questo errore?

Lint consiglia di utilizzare il ciclo di vita delle viste del frammento ( viewLifecycleOwner) anziché il ciclo di vita del frammento stesso ( this). Ian Lake e Jeremy Woods di Google esaminano la differenza come parte di questa presentazione del Summit degli sviluppatori Android , e Ibrahim Yilmaz copre le differenze in questo post Medium In breve:

  • viewLifecycleOwnerè legato a quando il frammento ha (e perde) la sua UI ( onCreateView(), onDestroyView())

  • thisè legato al ciclo di vita complessivo del frammento ( onCreate(), onDestroy()), che può essere sostanzialmente più lungo

Come sbarazzarsene?

Sostituire:

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

con:

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

Nel tuo codice attuale, se onDestroyView()viene chiamato, ma onDestroy()non lo è, continuerai a osservare LiveData, forse l'arresto anomalo quando provi a popolare un inesistente RecyclerView. Usando viewLifecycleOwner, eviti quel rischio.


6
Nota che dovresti comunque usare "this" in caso di DialogFragment (e probabilmente ogni frammento che non restituisce una vista per onCreateView. Altrimenti otterrai un'eccezione:IllegalStateException: Can't access the Fragment View's LifecycleOwner when getView() is null i.e., before onCreateView() or after onDestroyView()
sviluppatore Android

@androiddeveloper Potresti ancora usare lifeCycleOwner in onViewCreated e in seguito?
incontro

@jontro Abbastanza sicuro che puoi. Provalo e fammi sapere :)
sviluppatore Android

@androiddeveloper sembra funzionare bene!
incontro

1

Invece di thisusare viewLifecycleOwnerper osservareLiveData

viewModel.students.observe(viewLifecycleOwner, Observer {
    //TODO: populate recycler view
})
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.