androidandroid-livedataandroid-architecture-componentsandroid-livedata-transformations

Android LiveData: Difference between LiveData provided as method or as variable


I am facing a strange, but huge difference in behaviour between observing LiveData that is exposed as a method and LiveData that is exposed as variable. Consider the following code in your ViewModel:

LiveData as method

private val carApiCall = carRepository.getCar(carId)

fun getCarColors() = Transformations.switchMap(carApiCall ) { resource ->
    when (resource.resourceStatus) {
        ResourceStatus.SUCCESS -> databaseRepository.getCarColors(carId)
    }
}

LiveData as variable

private val carApiCall = carRepository.getCar(carId)

val carColors = Transformations.switchMap(carApiCall ) { resource ->
    when (resource.resourceStatus) {
        ResourceStatus.SUCCESS -> databaseRepository.getCarColors(carId)
    }
}

As you can see, the only difference is how carColors are observable by the outside. First as as method getCarColors() then as a public variable carColors.

The car colors are observed and used by both the fragment and a few times in the xml data-binding layout.

When using the variable approach, all works fine. As soon as the API call was successful, the code requests the car colors from the database once.

When using the method approach, the API call is executed once, but the Transformation on it is called up to 20 times! Why does it behave like that?

To be clear: Both code examples end up with a working result, but for some reason the second one gets executed/called many times, although the transformed apiCall is only changed once.


Solution

  • When you use it as a method, the method is called separately each time you try to access it. Every time you call getCarColors(), it will execute the function you wrote.

    When used as a variable, the code is executed only the first time - this is called variable initialization. After a variable is initialized, its value is stored in the memory, so the function you use for initialization is called only once.