Search code examples
androidkotlinandroid-databindingandroid-architecture-components

AppCompatActivity, ViewModel and Data Binding


Trying to figure out the Google's recent tools and concepts: LifecycleActivity, ViewModel and Data Binding.

So imagine there is a FooActivity that extends AppCompatActivity(to be able to use Support library) and implements LifecycleOwner interface (from reference: required to use LiveData):

FooActivity.kt:

class FooActivity: AppCompatActivity(), LifecycleObserver {
  ...

We set the binding:

  ..
  private val mBinding: by lazy {
    DataBindingUtil.setContentView<ActivityFooBinding>(this, R.layout.activity_foo)
  }
  ..

We set activity's ViewModel, and attach our barObserver (which should observe changes of bar inside a ViewModel, which is just a List of Strings):

  ..
  val viewModel = ViewModelProviders.of(this).get(FooViewModel::class.java)
  viewModel.getBars()?.observe(this, barObserver)
  viewModel.init() // changes bar, should trigger Observer's onChanged
  ..

And finally we define barObserver:

  ..
  class BarObserver : Observer<List<String>> {
    override fun onChanged(p0: List<String>?) {
      Log.d("Say", "changed:")
    }
  }
  barObserver = BarObserver()
  ..

Questions:

  1. Why does Observers onChange never triggered?
  2. Should one use LifeCycleOwner``getLifecycle instead of using Observer?
  3. Any other thoughts?

Edit: As the reference states:

LiveData is a data holder class that can be observed within a given lifecycle. This means that an Observer can be added in a pair with a LifecycleOwner, and this observer will be notified about modifications of the wrapped data only if the paired LifecycleOwner is in active state. LifecycleOwner is considered as active, if its state is STARTED or RESUMED. An observer added via observeForever(Observer) is considered as always active and thus will be always notified about modifications. For those observers, you should manually call removeObserver(Observer).

Changing:

enter code hereviewModel.getBars()?.observe(this, barObserver)

to:

viewModel.getBars()?.observeForever(barObserver)

didn't to the trick. onChange still never triggered.

Edit2:

FooActivity.kt:

replaced with:

class FooActivity: AppCompatActivity(), LifecycleRegistryOwner{
  override fun getLifecycle(): LifecycleRegistry {
        var lifecycle = LifecycleRegistry(this)
        lifecycle.addObserver(barObserver)
        return lifecycle
    }

FooViewModel:

  ..
  private var mBar = MutableLiveData<List<String>>()
  ..
  mBar.value = listValueOf("1", "2", "3")
  ..
  fun getBar(): LiveData<List<String>>? = mBar
  ..

Solution

  • If you are not extending LifecycleActivity then your activity should implement LifecycleRegistryOwner instead of LifecycleObserver. Check out the docs.

    And then you can pass it to liveData.observe(lifecycleOwner, observer)