Sử dụng viewLifecyclOwner làm LifecyclOwner


17

Tôi có một đoạn:

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

Trong đoạn của tôi, tôi có một ví dụ của StudentViewModel được khởi tạo onViewCreated(...).

In, StudentsViewModel, studentslà một LiveData:

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

Quay lại MyFragment, trong chức năng updateStudentList()tôi nhận được lỗi trình biên dịch phàn nàn thistham số tôi truyền vào .observe(this, Observer{...})đóUse viewLifecycleOwner as the LifecycleOwner

Tại sao tôi nhận được lỗi này? Làm thế nào để thoát khỏi nó?

Câu trả lời:


33

Tại sao tôi nhận được lỗi này?

Lint khuyên bạn nên sử dụng vòng đời của các khung nhìn của đoạn ( viewLifecycleOwner) thay vì vòng đời của chính đoạn đó ( this). Ian Lake và Jeremy Woods của Google vượt qua sự khác biệt như một phần của bài thuyết trình Hội nghị thượng đỉnh dành cho nhà phát triển Android này và Ibrahim Yilmaz trình bày về sự khác biệt trong bài trung bình này Tóm lại:

  • viewLifecycleOwnerđược gắn với khi đoạn có (và mất) UI của nó ( onCreateView(), onDestroyView())

  • thisđược gắn với vòng đời tổng thể của mảnh ( onCreate(), onDestroy()), có thể dài hơn đáng kể

Làm thế nào để thoát khỏi nó?

Thay thế:

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

với:

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

Trong mã hiện tại của bạn, nếu onDestroyView()được gọi, nhưng onDestroy()không, bạn sẽ tiếp tục quan sát LiveData, có lẽ bị sập khi bạn cố gắng điền vào một thứ không tồn tại RecyclerView. Bằng cách sử dụng viewLifecycleOwner, bạn tránh được rủi ro đó.


6
Lưu ý rằng bạn vẫn nên sử dụng "cái này" trong trường hợp DialogFragment (và có thể mọi phân đoạn không trả về chế độ xem cho onCreateView. Nếu không, bạn sẽ có một ngoại lệ:IllegalStateException: Can't access the Fragment View's LifecycleOwner when getView() is null i.e., before onCreateView() or after onDestroyView()
nhà phát triển Android

@androiddeveloper Bạn vẫn có thể sử dụng lifeCyclOwner trong onViewCreated trở đi?
jontro

@jontro Khá chắc chắn bạn có thể. Hãy dùng thử và cho tôi biết :)
nhà phát triển Android

@androiddeveloper dường như làm việc tốt!
jontro

1

Thay vì thissử dụng viewLifecycleOwnerđể quan sátLiveData

viewModel.students.observe(viewLifecycleOwner, Observer {
    //TODO: populate recycler view
})
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.