Why there's a separate MutableLiveData subclass of LiveData?
In LiveData - Android Developer Documentation, you can see that for LiveData
, setValue()
& postValue()
methods are not public.
Whereas, in MutableLiveData - Android Developer Documentation, you can see that, MutableLiveData
extends LiveData
internally and also the two magic methods of LiveData
is publicly available in this and they are setValue()
& postValue()
.
setValue()
: set the value and dispatch the value to all the active observers, must be called from main thread.
postValue()
: post a task to main thread to override value set by setValue()
, must be called from background thread.
So, LiveData
is immutable. MutableLiveData
is LiveData
which is mutable & thread-safe.
When to use MutableLiveData and LiveData
LiveData has no public method to modify its data.
LiveData<User> getUser() {
if (userMutableLiveData == null) {
userMutableLiveData = new MutableLiveData<>();
}
return userMutableLiveData
}
You can't update its value like getUser().setValue(userObject)
or getUser().postValue(userObject)
So when you don't want your data to be modified use LiveData
If you want to modify your data later use MutableLiveData
Why are MutableLiveData variables declared with equals sign (=)?
Kotlin auto detects the type, so you do not need to specify it. These are equivalent
val foo: Int = 123
val foo = 123
However, if you have a variable that is initialized later, you must provide the type, as otherwise the compiler can't determine what type it is. For instance,
class MyClass {
val foo: Int // must specify type
init {
foo = /* compute foo */
}
}
It has nothing to do with LiveData
or MutableLiveData
.
LiveData works with recyle view but MutableLiveData don't. Why?
Try MediatorLiveData
instead of mutable
Repository:
class TipRepository (private val tipDAO: TipDAO){
// Room executes all queries on a separate thread.
// Observed LiveData will notify the observer when the data has changed.
val allTips: LiveData<List<Tip>> = tipDAO.getAll()
// The suspend modifier tells the compiler that this must be called from a
// coroutine or another suspend function.
suspend fun insert (tip: Tip){
tipDAO.insert(tip)
}
fun getAlphabetizedTips (): LiveData<List<Tip>> {
return tipDAO.getAlphabetizedTips()
}
suspend fun delete (tip: Tip) {
tipDAO.delete(tip)
}
Model view
class TipViewModel (application: Application): AndroidViewModel (application) {
private val repository : TipRepository
val allTips = MediatorLiveData<List<Tip>()
init {
val tipDAO = TipRoomDatabase.getDatabase(application).tipDao()
repository = TipRepository(tipDAO)
allTips.addSource(repository.allTips){
this.allTips.value = it
}
}
Convert LiveData to MutableLiveData
Call me crazy but AFAIK there is zero reason to use a MutableLiveData for the object that you received from the DAO.
The idea is that you can expose an object via LiveData<List<T>>
@Dao
public interface ProfileDao {
@Query("SELECT * FROM PROFILE")
LiveData<List<Profile>> getProfiles();
}
Now you can observe them:
profilesLiveData.observe(this, (profiles) -> {
if(profiles == null) return;
// you now have access to profiles, can even save them to the side and stuff
this.profiles = profiles;
});
So if you want to make this live data "emit a new data and modify it", then you need to insert the profile into the database. The write will re-evaluate this query and it will be emitted once the new profile value is written to db.
dao.insert(profile); // this will make LiveData emit again
So there is no reason to use getValue
/setValue
, just write to your db.
Related Topics
How to Clear Specific Activity from the Stack History
How to Create a Dialogfragment Without Title
Call Getlayoutinflater() in Places Not in Activity
Android 4.2: Back Stack Behaviour with Nested Fragments
How to Store Image Retrieved from Url in a SQLite Database
Using Intent.Action_Pick for Specific Path
Android Supporting Multiple Resolution with Multiple Layout Folder
Picasso Loading of Image Spawned Inside Asynctask
Android 3.1.1 - Failed Resolution Of: Lcom/Google/Android/Gms/Common/Internal/Zzbq;
Android Sharedpreferences Limitations
Configuration on Demand Is Not Supported by the Current Version of the Android Gradle Plugin
Android SQLite Selection Args[] with Int Values
What Does the Filter Parameter to Createscaledbitmap Do
Change Navigationview Items When User Is Logged
Android: What Is Better - Multiple Activities or Switching Views Manually