62

when to use MutableLiveData and LiveData means the area of using the methods :

MutableLiveData<User> getUser() {
    if (userMutableLiveData == null) {
        userMutableLiveData = new MutableLiveData<>();
    }
    return userMutableLiveData;
}

and when to use this,

LiveData<User> getUser() {
    if (userMutableLiveData == null) {
        userMutableLiveData = new MutableLiveData<>();
    }
    return userMutableLiveData
}
Jeel Vankhede
  • 11,592
  • 2
  • 28
  • 58
vinayak
  • 623
  • 1
  • 5
  • 8
  • 5
    Basically, you expose it as `LiveData` to UI *(Activity/Fragment)* as it can't modify it directly and expose it to Repositories as `MutableLiveData` *(if using in project)*. – Jeel Vankhede Apr 30 '19 at 06:08
  • 2
    please make me understand by giving one simple example – vinayak Apr 30 '19 at 06:12

8 Answers8

71

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

shb
  • 5,957
  • 2
  • 15
  • 32
  • 5
    what you are saying we cant update live data values in wrong. LiveDate is not synchronised but Mutable live data in synchronised and also have ability to invoke observer from Worker thread using its postValue methods. So when you don't want your data to be modified use LiveData If you want to modify your data later use MutableLiveData` this not right statement. https://stackoverflow.com/questions/46814158/why-theres-a-separate-mutablelivedata-subclass-of-livedata – Sohail Zahid Jun 13 '20 at 06:12
  • I quite didn't understand your comment, the link also iterates the same message. `LiveData` is an abstract class with protected `setValue` and `postValue` methods and is supposed to be used to restrict modifications in activity or fragments. Could you please provide an example where you can update a `LiveData` value with `setValue` or `postValue`? – shb Jun 13 '20 at 07:59
  • 1
    But, can't you just cast the returned LiveData to MutableLiveData? – Tayyab Mazhar Jul 13 '20 at 16:29
  • 2
    MVVM newbie here. I learnt that `LiveData` is [the sole way](https://android.jlelse.eu/mvvm-how-view-and-viewmodel-should-communicate-8a386ce1bb42) for `ViewModel` to communicate to `View`. What's the point of an immutable `LiveData` then? – Minh Nghĩa Dec 08 '20 at 08:31
23

Let's say you're following MVVM architecture and having LiveData as observable pattern from ViewModel to your Activity. So that you can make your variable as LiveData object exposing to Activity like below :

class MyViewModel : ViewModel() {
    // LiveData object as following
    var someLiveData: LiveData<Any> = MutableLiveData()

    fun changeItsValue(someValue: Any) {
        (someLiveData as? MutableLiveData)?.value = someValue
    }
}

And now at Activity part, you can observe LiveData but for modification you can call method from ViewModel like below :

class SomeActivity : AppCompatActivity() {
    // Inside onCreateMethod of activity
    val viewModel = ViewModelProviders.of(this)[MyViewModel::class.java]
    viewModel.someLiveData.observe(this, Observer{
        // Here we observe livedata
    })
    viewModel.changeItsValue(someValue) // We call it to change value to LiveData
    // End of onCreate
}
Jeel Vankhede
  • 11,592
  • 2
  • 28
  • 58
  • 3
    @c0ming Another way to achieve this by creating two objects in ViewModel. `MutableLiveData` object can be private & manipulated by setter method while public object can be `LiveData` reassigned from above private object. – Jeel Vankhede Dec 18 '20 at 08:01
  • 1
    @JeelVankhede You're right my friend, this is the recommended way on the official Udacity couse made by Google developers. It's the way to encapsulate the information we don't want our classes to edit. Check out the course at: https://classroom.udacity.com/courses/ud9012 – Ramiro G.M. Feb 12 '21 at 01:03
16

LiveData has no public available methods to update the stored data. The MutableLiveData class exposes the setValue(T) and postValue(T) methods public and you must use these if you need to edit the value stored in a LiveData object. Usually MutableLiveData is used in the ViewModel and then the ViewModel only exposes immutable LiveData objects to the observers. Please take a look at this reference.

Ole Pannier
  • 3,208
  • 9
  • 22
  • 33
15

We should return LiveData in order to prevent views (or other observers) from accident value modification.

Having:

    LiveData<User> getUser() {
       if (userMutableLiveData == null) {
           userMutableLiveData = new MutableLiveData<>();
       }
       return userMutableLiveData
    }

you can't write in your activity / fragment: getUser().setValue(...). This makes your code less bug prone.

Derek K
  • 2,756
  • 1
  • 21
  • 37
1

Best Approach of using MutableLiveData in seprate class Like

public class SharedViewModel extends ViewModel {
private MutableLiveData<CharSequence>text = new MutableLiveData<>();

public void setText(CharSequence input)
{
    text.setValue(input);
}

public LiveData<CharSequence> getText(){
    return text;

}
}

Livedata is Used in Fragment Like

private SharedViewModel viewModel;

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        //No Need to initate further
        viewModel = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
        viewModel.getText().observe(getViewLifecycleOwner(), new Observer<CharSequence>() {
            @Override
            public void onChanged(@Nullable CharSequence charSequence) {
                editText.setText(charSequence);
            }
        });
    }

in Fragment Class be Like

public class FragmentA extends Fragment {
    private SharedViewModel viewModel;
    private EditText editText;
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_a, container, false);
        editText = v.findViewById(R.id.edit_text);
        Button button = v.findViewById(R.id.button_ok);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                viewModel.setText(editText.getText());
            }
        });
        return v;
    }
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        viewModel = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
        viewModel.getText().observe(getViewLifecycleOwner(), new Observer<CharSequence>() {
            @Override
            public void onChanged(@Nullable CharSequence charSequence) {
                editText.setText(charSequence);
            }
        });
    }
}
pankaj jha
  • 49
  • 1
  • 9
1

The main difference between LiveData and MutableLiveData is:

  • you can change the value of MutableLiveData but LiveData does not allow you to change it's value
  • LiveData only allows you to observe its value.

They are usually used together. so MutableLiveData is used to record the changed value and LiveData is used to notify the UI about the change value.

0

Use LiveData when you don't want to modify it because the methods like setValue() & postValue() are not public .Live data takes care itself by calling them internally.

Where as in MutableLiveData setValue() postValue() are exposed ie public.You can change set values by calling these methods.

Find more details here : https://blog.mindorks.com/livedata-setvalue-vs-postvalue-in-android

Ajay Chauhan
  • 1,471
  • 4
  • 17
  • 37
0

For best practice, readability and avoid error prone by mistake just like MutableList vs List in Kotlin. Use Mutable is when you want its data to be modified or you want to re assign a new value on it.

We use MutableLiveData when we want to make its value writable or can be change anytime.

We use LiveData when we just want to read and listen to any updates made by MutableLiveData. Thus we have this kind of code as sample

private var filterAsset = MutableLiveData<String>().apply{
        value = "Empty"
    }

    //public method to set a new value on filterAsset
    fun setFilterData(assetName: String){
        filterAsset.value = assetName
    }

// We can use this to listen on any updates from filterAsset
val assetFilterUpdates: LiveData<String> = filterAsset


// Inside your Fragment/Activity
// You can listen to the update in Fragment or Activity like this 
yourViewModel.assetFilterUpdates.observe(viewLifecycleOwner, { value ->

            // Use the updated value here

        })