ใช้ viewLifecycleOwner เป็น LifecycleOwner


17

ฉันมีชิ้นส่วน:

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

ในส่วนของฉันฉันมีตัวอย่างของ StudentsViewModel onViewCreated(...)ซึ่งจะเริ่มใน

ในStudentsViewModel, studentsเป็นLiveData:

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

กลับไปที่MyFragmentฟังก์ชั่นupdateStudentList()ฉันได้รับข้อผิดพลาดของคอมไพเลอร์บ่นว่าthisพารามิเตอร์ที่ฉันส่งไป.observe(this, Observer{...})นั้นUse viewLifecycleOwner as the LifecycleOwner

ทำไมฉันถึงได้รับข้อผิดพลาดนี้? จะกำจัดมันได้อย่างไร?

คำตอบ:


32

ทำไมฉันถึงได้รับข้อผิดพลาดนี้?

ผ้าสำลีแนะนำให้คุณใช้วงจรชีวิตของมุมมองของชิ้นส่วน ( viewLifecycleOwner) แทนวงจรชีวิตของชิ้นส่วนเอง ( this) Ian Lake และ Jeremy Woods ของ Google กล่าวถึงความแตกต่างซึ่งเป็นส่วนหนึ่งของงานนำเสนอ Android Developer Summitนี้และ Ibrahim Yilmaz ครอบคลุมความแตกต่างในโพสต์สื่อนี้สั้น ๆ :

  • viewLifecycleOwnerเชื่อมโยงกับเมื่อส่วนมี (และสูญเสีย) UI ( onCreateView(), onDestroyView())

  • thisเชื่อมโยงกับวงจรชีวิตโดยรวมของชิ้นส่วน ( onCreate(), onDestroy()) ซึ่งอาจมีความยาวขึ้นอย่างมาก

จะกำจัดมันได้อย่างไร?

แทนที่:

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

ด้วย:

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

ในรหัสของคุณในปัจจุบันถ้าonDestroyView()จะเรียกว่า แต่onDestroy()ไม่ได้คุณจะยังคงสังเกตอาจจะล้มเหลวเมื่อคุณพยายามประชากรไม่มีอยู่จริงLiveData RecyclerViewโดยการใช้viewLifecycleOwnerคุณหลีกเลี่ยงความเสี่ยงนั้น


6
โปรดทราบว่าคุณยังควรใช้ "this" ในกรณีของ DialogFragment (และอาจเป็นทุกส่วนที่ไม่ส่งคืนมุมมองสำหรับ onCreateView มิฉะนั้นคุณจะได้รับข้อยกเว้น:IllegalStateException: Can't access the Fragment View's LifecycleOwner when getView() is null i.e., before onCreateView() or after onDestroyView()
พัฒนา android

@androiddeveloper คุณยังสามารถใช้ lifeCycleOwner ใน onViewCreated และต่อไปได้หรือไม่
jontro

@ jontro ค่อนข้างแน่ใจว่าคุณสามารถ ลองและแจ้งให้เราทราบ :)
นักพัฒนา Android

@androiddeveloper ดูเหมือนว่าจะทำงานได้ดี!
jontro

1

แทนที่จะthisใช้viewLifecycleOwnerเพื่อสังเกตLiveData

viewModel.students.observe(viewLifecycleOwner, Observer {
    //TODO: populate recycler view
})
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.