Use viewLifecycleOwner como o LifecycleOwner

17

Eu tenho um fragmento:

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

No meu fragmento, tenho uma instância de StudentsViewModel que é iniciada em onViewCreated(...).

Em, StudentsViewModel, studentsé um LiveData:

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

De volta a MyFragment, na função updateStudentList(), recebo um erro do compilador reclamando do thisparâmetro que eu passei para .observe(this, Observer{...})aqueleUse viewLifecycleOwner as the LifecycleOwner

Por que recebo esse erro? Como se livrar dele?

user842225
fonte

Respostas:

33

Por que recebo esse erro?

Lint está recomendando que você use o ciclo de vida das visualizações do fragmento ( viewLifecycleOwner) em vez do ciclo de vida do próprio fragmento ( this). Ian Lake e Jeremy Woods, do Google, discutem a diferença como parte desta apresentação do Android Developer Summit , e Ibrahim Yilmaz aborda as diferenças neste post do Medium. Em poucas palavras:

  • viewLifecycleOwnerestá vinculado a quando o fragmento tem (e perde) sua interface do usuário ( onCreateView(), onDestroyView())

  • thisestá vinculado ao ciclo de vida geral do fragmento ( onCreate(), onDestroy()), que pode ser substancialmente mais longo

Como se livrar dele?

Substituir:

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

com:

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

No seu código atual, se onDestroyView()for chamado, mas onDestroy()não for, você continuará observando o LiveData, talvez travando ao tentar preencher um inexistente RecyclerView. Ao usar viewLifecycleOwner, você evita esse risco.

CommonsWare
fonte
6
Observe que você ainda deve usar "this" no caso de DialogFragment (e provavelmente todos os fragmentos que não retornam uma exibição para onCreateView. Caso contrário, você receberá uma exceção:IllegalStateException: Can't access the Fragment View's LifecycleOwner when getView() is null i.e., before onCreateView() or after onDestroyView()
android developer
@androiddeveloper Você ainda pode usar o lifeCycleOwner no onViewCreated e em diante?
jontro 30/03
@ Jontro Tenho certeza que você pode. Experimente e me avise :)
desenvolvedor android
@androiddeveloper parece funcionar bem!
jontro 31/03
1

Em vez de thisusar viewLifecycleOwnerpara observarLiveData

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