Gunakan viewLifecycleOwner sebagai LifecycleOwner

17

Saya memiliki sebuah fragmen:

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

Dalam fragmen saya, saya memiliki instance StudentsViewModel yang dimulai pada onViewCreated(...).

Dalam, StudentsViewModel, studentsadalah LiveData:

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

Kembali ke MyFragment, dalam fungsi updateStudentList()saya mendapatkan error compiler mengeluh thisparameter saya melewati ke .observe(this, Observer{...})yangUse viewLifecycleOwner as the LifecycleOwner

Mengapa saya mendapatkan kesalahan ini? Bagaimana cara menghilangkannya?

pengguna842225
sumber

Jawaban:

33

Mengapa saya mendapatkan kesalahan ini?

Lint merekomendasikan agar Anda menggunakan siklus hidup tampilan fragmen ( viewLifecycleOwner) daripada siklus hidup fragmen itu sendiri ( this). Ian Lake dan Jeremy Woods dari Google membahas perbedaan sebagai bagian dari presentasi KTT Pengembang Android ini , dan Ibrahim Yilmaz membahas perbedaan dalam postingan Medium ini Singkatnya:

  • viewLifecycleOwnerterkait ketika fragmen memiliki (dan kehilangan) UI-nya ( onCreateView(), onDestroyView())

  • thisterikat pada siklus hidup keseluruhan fragmen ( onCreate(), onDestroy()), yang mungkin jauh lebih lama

Bagaimana cara menghilangkannya?

Menggantikan:

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

dengan:

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

Dalam kode Anda saat ini, jika onDestroyView()dipanggil, tetapi onDestroy()tidak, Anda akan terus mengamati LiveData, mungkin macet ketika Anda mencoba mengisi yang tidak ada RecyclerView. Dengan menggunakan viewLifecycleOwner, Anda menghindari risiko itu.

CommonsWare
sumber
6
Perhatikan bahwa Anda masih harus menggunakan "ini" untuk DialogFragment (dan mungkin setiap fragmen yang tidak mengembalikan tampilan untuk onCreateView. Jika tidak, Anda akan mendapatkan pengecualian:IllegalStateException: Can't access the Fragment View's LifecycleOwner when getView() is null i.e., before onCreateView() or after onDestroyView()
pengembang android
@androiddeveloper Anda masih bisa menggunakan lifeCycleOwner di onViewCreated dan seterusnya?
jontro
@jontro Cukup yakin Anda bisa. Cobalah dan beri tahu saya :)
pengembang android
@androiddeveloper sepertinya bekerja dengan baik!
jontro
1

Alih-alih thisdigunakan viewLifecycleOwneruntuk mengamatiLiveData

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