LiveData

LiveData is a data holder class that is lifecycle aware. It keeps a value and allows this value to be observed. Observation refers to the observer pattern, which is when an object, called the subject, has a list of associated objects, called observers. When the subject's state changes, it notifies all of the observers, usually by calling one of their methods.

LiveData

It is a data holder because it wraps data like such:

MutableLiveData<String> name = new MutableLiveData<String>();
name.setValue("Lyla");

This is a LiveData instance that is holding a String object and its current value is "Lyla".

The general way to create an observer for a LiveData object is this:

name.observe(<LIFECYCLE OWNER>, newName -> {
   // Do something when the observer is triggered; usually updating the UI
});

A LifecycleOwner is passed into the observe method. This is the LifecycleOwner that is associated with the Observer.

Simply wrapping your @Query return type with LiveData provides you with database observers for minimal extra effort. You also move the reference to the database, from the activity, to a ViewModel.

LiveData is Usually stored in the ViewModel object. LiveDate is in an active state if the observer's lifecycle is in either the STARTED or RESUMED states. LiveData can be observed by many listeners, each tied to a lifecycle owner such as a Fragment or Activity.

To change the data inside LiveData, we can use the setValue method from a main thread or postValue from a background thread. If we call postValue multiple times before the main thread executed a posted task, only the last value will be dispatched.

An observer can be paired with an object implementing the LifecycleOwner interface.

Advantages

  • Ensures UI matches data state via Observer pattern.
  • Observer gets updates to the data while the Lifecycle is in an active state (STARTED or RESUMED)
  • Observer gets up-to-date data when the LifecycleOwner restarts due to a configuration change or is restarted from the back stack
  • No memory leaks. Bound to the Lifecycle objects and clean up when lifecycle is destroyed.
  • No crahses due to stopped lifecycles handling
  • Always up to date data
  • Proper configuration changes
  • Sharing resources
  • Removed Observer when is removed when LifecycleOwner is destroyed

Steps to Using

  1. Create an instance of LiveData, in ViewModel
  2. Create Observer Object that defines onChange()
  3. Attach Observer to LiveData using observe() method
public class NameViewModel extends ViewModel {

// Create a LiveData with a String
private MutableLiveData<String> mCurrentName;

    public MutableLiveData<String> getCurrentName() {
        if (mCurrentName == null) {
            mCurrentName = new MutableLiveData<String>();
        }
        return mCurrentName;
    }

// Rest of the ViewModel...
}
public class NameActivity extends AppCompatActivity {

    private NameViewModel mModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Other code to setup the activity...

        // Get the ViewModel.
        mModel = ViewModelProviders.of(this).get(NameViewModel.class);

        // Create the observer which updates the UI.
        final Observer<String> nameObserver = new Observer<String>() {
            @Override
            public void onChanged(@Nullable final String newName) {
                // Update the UI, in this case, a TextView.
                mNameTextView.setText(newName);
            }
        };

        // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
        mModel.getCurrentName().observe(this, nameObserver);
    }
}

Note LiveData and it's subclasses contain both a setValue() and a postValue() method. The difference is that setValue() must be called from the main thread. postValue() is for when the call occurs off of the main thread.

Advantages of attaching in onCreate():

  • Ensures no redundant calls are made.
  • Ensures activity or fragement data is populated when it starts.

Transform LiveData

Transformations class which includes helper methods to tranform data. Lazy. It has two methods: map and switchMap. Both take two arguments: source LiveData and a function, and create a new LiveData, which behaves according to the following logic: it reacts to changes of source LiveData and applies the given function.

SwitchMap

 class MyViewModel extends ViewModel {
    private final PostalCodeRepository repository;
    private final MutableLiveData<String> addressInput = new MutableLiveData();
    public final LiveData<String> postalCode =
            Transformations.switchMap(addressInput, (address) -> {
                return repository.getPostCode(address);
             });

  public MyViewModel(PostalCodeRepository repository) {
      this.repository = repository
  }

  private void setInput(String address) {
      addressInput.setValue(address);
  }
}

results matching ""

    No results matching ""