Introduction
LiveData is an observable data storage class. Unlike regular observable classes, LiveData is lifecycle aware and responds to the lifecycle of a component (activity, fragment or service). This ensures that LiveData only updates component observers that are in an active lifecycle state.
If the life cycle of the observer component is in the Started or Resumed state, LiveData will consider the observer to be in the active state. LiveData will only notify active observers of updates. Inactive observers will not receive update notifications.
The observed object needs to implement the LifecycleOwner interface. At the same time, we can register a corresponding observer LifecycleObserver . Based on the relationship between the observer and the observed object, when the state of the corresponding observer LifecycleObserver component becomes Destroyed, it can automatically Remove this observer. This is especially useful for Activities and Fragments, since they can safely observe LiveData objects without worrying about leaks (the system immediately unsubscribes the activity and fragment when their lifecycle is destroyed).
Advantages of LiveData
1. Automatically update interface data
LiveData follows the observer pattern. When the underlying data changes, LiveData notifies the Observer object. There's no need to update the UI every time your app's data changes, because the observer will do it for you.
2. There will be no memory leaks
The system immediately unsubscribes activities and fragments when their lifecycle is destroyed.
3. No crashes due to the stop of the Activity
If the observer's lifecycle is inactive, it will not receive any LiveData events.
4. No need to manually handle the life cycle
The interface component only observes the changes of LiveData data, and will not stop or resume the observation. LiveData will automatically manage all of these operations as it senses and responds to relevant lifecycle state changes.
5. Data is always up to date
Receive the latest data when the life cycle changes from an inactive state to an active state. For example, an Activity that was once in the background receives the latest data as soon as it returns to the foreground.
6. Cooperate with configuration changes
If an activity or fragment is recreated due to a configuration change such as a device rotation, it immediately receives the latest available data.
7. Shared resources
You can use the singleton pattern to extend the LiveData object to encapsulate system services so that they can be shared across applications. LiveData
The object connects to the system service once, and then any observer that needs the corresponding resource simply observes LiveData
the object.
Use of the LiveData object
The steps to use are as follows:
1. Create a LiveData instance to store data, which is usually done in ViewModel.
2. Create an Observer object and implement the onChaned() method, which is used to respond to changes in LiveData data, thereby responding. Usually we create Observer objects in components (Activity, Fragment).
3. Use the observe() method to connect the Observer and LiveData objects. The observe() method uses the LifecycleOwner method to make the Observer object subscribe to the LiveData object so that it can receive notifications about data updates.
Notice! !
In the absence of an associated LifecycleOwner object, we can use observeForever(Observer) to register an Observer observer. The Observer in this case is always considered active, so it will always be notified about changes to the LiveData. And these observers can be manually removed by means of removeObserver(Observer).
When we update the value stored in the LiveData object, all Observer observers registered with the LiveData will be triggered ( as long as the class component that implements the LifecycleOwner interface is active ).
1. Create a LiveData object
LiveData is a container that can be used for any data, including implementable Collections
objects such as List
. LiveData objects are usually implemented in ViewModel objects and can be accessed through getter methods, as shown in the following example:
public class NameViewModel extends ViewModel {
// 创建一个 String 数据类型的 LiveData 对象。
private MutableLiveData<String> currentName;
public MutableLiveData<String> getCurrentName() {
if (currentName == null) {
currentName = new MutableLiveData<String>();
}
return currentName;
}
// Rest of the ViewModel...
}
Note : Make sure
LiveData
you store your objects inViewModel
Objects instead of storing them in Activities or Fragments for the following reasons:
- Avoid too large Activity and Fragment. These components should only be responsible for displaying data, not storing data state.
- Detaches
LiveData
the instance from a specific Activity or Fragment instance, allowingLiveData
the object to survive configuration changes.
2. Observing the LiveData object
Normally, a component's onCreate()
method is the right time to start observing the LiveData object for the following reasons:
- Make sure the system doesn't make too many method calls from within your Activity's or Fragment's methods.
onResume()
- Make sure that the Activity or Fragment has data that can be displayed immediately after it becomes active. When an application component is in the STARTED state, it receives the latest value from the object it is observing
LiveData
.
Normally LiveData only sends update notifications when the data changes, and only to active observers. Observers also receive updates when they change from inactive to active. Also, if the observer changes from inactive to active a second time, it will only receive updates if the value has changed since the last time it became active.
The following sample code illustrates how to start observing LiveData
objects:
public class NameActivity extends AppCompatActivity {
private NameViewModel model;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 获取 ViewModel 对象.
model = new ViewModelProvider(this).get(NameViewModel.class);
// 创建 observer 更新 UI.
final Observer<String> nameObserver = new Observer<String>() {
@Override
public void onChanged(@Nullable final String newName) {
// Update the UI
nameTextView.setText(newName);
}
};
// 观察这个 LiveData,并将该 Activity 作为 LifecycleOwner 和观察者传递进来。
model.getCurrentName().observe(this, nameObserver);
}
}
After calling observe() and passing in nameObserver 参数
, the system will call the onChanged() method immediately and provide currentName
the latest value stored in . If LiveData
the object has not already mCurrentName
had a value set in it, the system will not be called onChanged() 方法
.
3. Update the LiveData object
LiveData has no publicly available methods to update stored data. The MutableLiveData class will expose setValue(T) and postValue(T) methods that you can use if you need to modify the value stored in the LiveData object. Usually it will be used in ViewModelMutableLiveData
.
After setting up the observer relationships, you can update LiveData
the object's value (as in the following example) so that all observers are triggered when the user taps a button:
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String anotherName = "John Doe";
model.getCurrentName().setValue(anotherName);
}
});
Calling in this example setValue(T)方法,
causes the observer to use the new value " ", and the onChanged()John Doe
method is called .