This is the 20th day of my participation in the Genwen Challenge

LiveData overview

Introduction to the

LiveData is an observable data holder class. Unlike a regular Observable, LiveData is lifecycle aware, which means it respects the lifecycle of other application components, such as activities, fragments, or services. This awareness ensures that LiveData updates only observers of application components that are in the active lifecycle state.

Note: To import LiveData components into your Android project, see Adding Android Architecture Components to your Project.

The instance

The basic use

class LiveDataDemoActivity : AppCompatActivity() {

    private lateinit var livedata: MutableLiveData<String>

    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_liva_data_demo)
        val observerForever = Observer<String> { println("LiveData observeForever changed : $it")}val observer = Observer<String> { println("LiveData observe changed : $it") }
        livedata = MutableLiveData()
        livedata.observeForever(observerForever)
        livedata.observe(this, observer)
    }

    override fun onResume(a) {
        super.onResume()
        livedata.value = "onResume"
    }

    override fun onPause(a) {
        super.onPause()
        livedata.value = "onPause"
    }

    override fun onStop(a) {
        super.onStop()
        livedata.value = "onStop"
    }

    override fun onDestroy(a) {
        super.onDestroy()
        livedata.value = "onDestroy"}}Copy the code

The log is as follows when the Activity is started

com.lingdage.androiddemo I/System.out: LiveData observeForever changed : onResume com.lingdage.androiddemo I/System.out: LiveData observe changed : onResume

After pressing the home button

com.lingdage.androiddemo I/System.out: LiveData observeForever changed : onPause com.lingdage.androiddemo I/System.out: LiveData observe changed : onPause com.lingdage.androiddemo I/System.out: LiveData observeForever changed : onStop

Reopen the app

com.lingdage.androiddemo I/System.out: LiveData observe changed : onStop com.lingdage.androiddemo I/System.out: LiveData observeForever changed : onResume com.lingdage.androiddemo I/System.out: LiveData observe changed : onResume

Press the return key

com.lingdage.androiddemo I/System.out: LiveData observeForever changed : onPause com.lingdage.androiddemo I/System.out: LiveData observe changed : onPause com.lingdage.androiddemo I/System.out: LiveData observeForever changed : onStop com.lingdage.androiddemo I/System.out: LiveData observeForever changed : onDestroy

** Note: Using observeForever** will listen for all lifecycle methods, so you’ll see life cycle functions like onDestroy() printed.

LiveData is an abstract class that we can’t use directly. Fortunately, Google has provided some simple implementations for us to use.

The MutableLiveData class is used to store data, which inherits LiveData and exposes setValue and postValue methods.

public class MutableLiveData<T> extends LiveData<T> {
    @Override
    public void postValue(T value) {
        super.postValue(value);
    }

    @Override
    public void setValue(T value) {
        super.setValue(value); }}Copy the code

Combined with the ViewModel

Create a LiveData object

The ViewModel is a class that prepares and manages data for an Activity or Fragment, and handles the rest of the application’s communication. Note that the ViewModel is only responsible for managing the DATA on the UI and has no control over anything else. It is bound to the component lifecycle and will only be destroyed when the Activity ends.

public class NameViewModel extends ViewModel {

    // Create a LiveData object that stores String
    private MutableLiveData<String> mCurrentName;

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

// The rest of the ViewModel...
}
Copy the code

In the initial state, the data in a LiveData object is not assigned.

Note: Be sure to store the LiveData object that updates the UI in a ViewModel object, not an Activity or fragment. Here’s why:

  • Avoid activities and Fragments that are too bloated. These UI controllers are now responsible for presenting the data, not storing the state of the data.
  • Decouple LiveData instances from specific activities or fragments and allow LiveData to survive configuration changes.

Observe the LiveData object

In most cases, you should start observing LiveData objects in the onCreate() method of an application component for the following reasons:

  • OnCreate is the first callback when the activity is created. OnResume and onStart are called back multiple times during the activity’s life cycle, making the call listening redundant.
  • Make sure your activities and Fragments get updates as soon as they become active and enter the started state, so start listening as soon as possible.

In general, LiveData notifies active observers of updates only when the data changes. There is one exception, however: observers can also receive updates when they go from inactive to active. Further, if the observer goes from inactive to active again, the observer will receive updates only if the data changes in the interim.

The following example code shows how to start observing a LiveData object:

public class NameActivity extends AppCompatActivity {

    private NameViewModel mModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Other code to set up the activity......
        / / get the ViewModel
        mModel = ViewModelProviders.of(this).get(NameViewModel.class);

        // Create an observer to update the UI
        final Observer<String> nameObserver = new Observer<String>() {
            @Override
            public void onChanged(@Nullable final String newName) { mNameTextView.setText(newName); }};// Pass the activity as the LifecycleOwner parameter along with the observer to start observing the LiveData
        mModel.getCurrentName().observe(this, nameObserver); }}Copy the code

In [observe ()] (developer. The android. Google. Cn/reference/a… Android), the arch, lifecycle. The Observer)) was introduced into nameObserver parameters and calls, onChanged () is triggered, immediately is used to provide the data stored by mCurrentName latest values. If the LiveData object has not already set a value for mCurrentName, onChanged() will not be called.

Update the LiveData object

LiveData’s methods for modifying data are not of public type and are only called internally, so MutableLiveData is used here, which exposes public methods for modifying data.

When you have set up the observer relationship, you can update the data in the LiveData object. As shown in the following example, all observers are notified when the user clicks the button:

mButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        String anotherName = "Naco Siren"; mModel.getCurrentName().setValue(anotherName); }});Copy the code

Calling setValue(T) in this example causes the observer to call its onChanged method with the new value Naco Siren. This example shows when a user clicks a button, but there are more cases where setValue() or postValue() is used, such as in response to a network request or when a database has finished loading: In either case, a call to setValue() or postValue() notifies the observer to update the UI.

Note: In the main thread, you must call setValue(T) to update the LiveData object. If the code is executed in a worker thread, you can update it with postValue(T).

reference

Official documentation: Overview of LiveData

Jetpack source code parsing – LiveData usage and how it works

Android LiveData source code anatomy

Android source code parsing -LiveData