Maher Tag
Maher Tag

Reputation: 229

Observe live data objects in fragment using activity context?

I'm using navigation bottom with shared ViewModel with all fragments inside navigation bottom but it throws this exception when recall fragment second time

java.lang.IllegalArgumentException: Cannot add the same observer with different lifecycles

I have tried to make all observers attached to activity not to it's fragment as below

1-Declare viewModel in fragemt

viewModel = activity?.run { 
          ViewModelProviders.of(this,viewModelFactory).get(SharedViewModel::class.java)
} ?: throw Exception("Invalid Activity")

2-Observer livedata object

viewModel.msg.observe(activity!!, Observer {
     Log.i(TAG,it)
})

3- remove observer

override fun onStop() {
    super.onStop()
    viewModel.msg.removeObservers(activity!!)
}

This code is working fine with me, but I wondering if my code is correct and working probably? thanks in advance

Upvotes: 3

Views: 12568

Answers (2)

Daniel
Daniel

Reputation: 2554

Why you are adding the observer to the fragment with the activity lifecycle? If you have some logic that needs to be executed when fragment is not active, add it to your activity. So instead of what you have, you need:

viewModel.msg.observe(this, Observer {
    Log.i(TAG, it)
})

What happens in your case is that each time you reopen your fragment, you attach a new observer with the same lifecycle, which seems to be an error. Livedata observers were specifically designed so that you don't have to write code for handling lifecycles manually.

Upvotes: 1

Shamsul Arafin Mahtab
Shamsul Arafin Mahtab

Reputation: 559

It is a common mistake we do while using live-data in fragment. Using this/activity on fragment can be duplicate. You should use viewLifecycleOwner for livedata observing in fragment.

viewModel.msg.observe(viewLifecycleOwner, Observer {
            Log.i(TAG,it)
        })

For more information, read this article https://medium.com/@cs.ibrahimyilmaz/viewlifecycleowner-vs-this-a8259800367b

You don't need to remove the observer manually.

Upvotes: 8

Related Questions