Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to enforce non-nullability of LiveData values?

Is there any way to enforce non-nullability of LiveData values? Default Observer implementation seems to have @Nullable annotation which forces an IDE to suggest that the value might be null and should be checked manually:

public interface Observer<T> {
    /**
     * Called when the data is changed.
     * @param t  The new data
     */
    void onChanged(@Nullable T t);
}
like image 639
Igor Bubelov Avatar asked Sep 29 '17 12:09

Igor Bubelov


People also ask

Can live data be null?

LiveData is written in Java. It does allow setting it's value to null .

How can data be stored in LiveData in a ViewModel?

Use LiveData for the app's data (word, word count and the score) in the Unscramble app. Add observer methods that get notified when the data changes, update the scrambled word text view automatically. Write binding expressions in the layout file, which are triggered when the underlying LiveData is changed.

What is MutableLiveData?

MutableLiveData. MutableLiveData is just a class that extends the LiveData type class. MutableLiveData is commonly used since it provides the postValue() , setValue() methods publicly, something that LiveData class doesn't provide.

What is observe to LiveData?

Observe LiveData objects To ensure that the activity or fragment has data that it can display as soon as it becomes active. As soon as an app component is in the STARTED state, it receives the most recent value from the LiveData objects it's observing.


2 Answers

If you use Kotlin, you can create much nicer non-null observe function with extension. There is an article about it. https://medium.com/@henrytao/nonnull-livedata-with-kotlin-extension-26963ffd0333

like image 136
Henry Tao Avatar answered Nov 15 '22 23:11

Henry Tao


A new option is available if you use Kotlin. You can replace LiveData with StateFlow. It is more suitable for Kotlin code and provides built-in null safety.

Instead of using:

class MyViewModel {
    val data: LiveData<String> = MutableLiveData(null) // the compiler will allow null here!
}

class MyFragment: Fragment() {
    model.data.observe(viewLifecycleOwner) {
        // ...
    }
}

You can use:

class MyViewModel {
    val data: StateFlow<String> = MutableStateFlow(null) // compilation error!
}

class MyFragment: Fragment() {
    lifecycleScope.launch {
        model.data.collect {
          // ...
        }
    }
}

StateFlow is part of coroutines and to use the lifecycleScope you need to add the lifecycle-extensions dependency:

implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"

Note that this API has been experimental before coroutines 1.4.0.

Here's some additional reading about replacing LiveData with StateFlow.

As Igor Bubelov pointed out, another advantage of this approach is that it's not Android specific so it can be used in shared code in multiplatform projects.

like image 45
Sir Codesalot Avatar answered Nov 16 '22 01:11

Sir Codesalot