Android Jetpack Components of LiveData study notes

Android Jetpack Components of Lifecycle study notes

Android Jetpack Components of LiveData study notes

Android Jetpack Components of ViewModel study notes

 

Demo Site: https://github.com/mengzhinan/Lifecycle_LiveData_ViewModel_demo

LiveData Google Docs: https://developer.android.google.cn/topic/libraries/architecture/livedata

 

Environment configuration:

Like Lifecycle, if the version of the SDK is less than 26, the dependency package needs to be imported android.arch.lifecycle。现在新建的项目默认都是 28 了,故不需要任何配置。

 

 

What is LiveData?

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

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

 

Simple and practical:

Let's first come to a Demo to briefly describe the use of LiveData.

public class DataUtil {

    private MutableLiveData<String> name = new MutableLiveData<>();

    public LiveData<String> getNameLiveData(){
        return name;
    }

    public void requestHead() {
        // 模拟请求网络或 DB,然后更新数据
        name.setValue("requestHead success");
    }

    public void requestList() {
        // 模拟请求网络或 DB,然后更新数据
        name.setValue("requestList success");
    }

}
public class LiveDataActivity extends AppCompatActivity {

    private DataUtil dataUtil;

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

        dataUtil = new DataUtil();
        dataUtil.getNameLiveData().observe(this, data -> {
            // 得到数据更新



        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        dataUtil.requestHead();
        dataUtil.requestList();
    }
}

Code description:

Sorry, the naming in the Demo code is arbitrary.

A MutableLiveData<String> type object name is defined in the DataUtil class, and name is an object using string type data.

Two methods, requestHead() and requestList() are defined in DataUtil to simulate network requests. And simulate the success of the network request in it, and update the value in the name object at the same time.

 

In LiveDataActivity, note that its parent class is AppCompatActivity.

Create a DataUtil object in LiveDataActivity, get the LiveData object name in it, and register an observer on the name.

In the appropriate place, metaphor the page onResume or onClick, call the requestHead() or requestList() method of the DataUtil object. When the data in the name object is changed, the observer registered in LiveDataActivity.DataUtil.MutableLiveData<String> will be notified of the data change.

Throughout the life cycle of LiveData, the name object will hold a string object value. When the value in name changes, all observer objects will be notified.

Through the above description, you should be able to understand the official explanation.

 

LiveData advantages:

1. Facilitate the separation and decoupling of UI logic and network requests in Activity.

2. LiveData will not have the risk of memory leaks.

 

Brief description of LiveData principle:

In the above example, why is MutableLiveData used?

By looking at the source code, it is found that MutableLiveData inherits LiveData. The purpose is to expose the postValue() and setValue() methods to the outside world. The difference between the two is that postValue() can be called in a non-UI thread, and then it will be switched to the UI thread through the handler.

 

 

We analyze from the setValue() method of MutableLiveData, why the data will be updated to the observer in the Activity after setValue().

Retrieved to LiveData's setValue() method:

@MainThread
protected void setValue(T value) {
    // 检查线程,如果是子线程,会直接抛异常
    assertMainThread("setValue");
    mVersion++;
    // 暂存数据
    mData = value;
    // 分发数据更改
    dispatchingValue(null);
}

Tracking method dispatchingValue(null);

private void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                considerNotify(initiator);
                initiator = null;
            } else {
                for (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

Loop through the collection of all observers and distribute messages one by one. The tracing method considerNotify(iterator.next().getValue());

private void considerNotify(ObserverWrapper observer) {
        if (!observer.mActive) {
            return;
        }
        // Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
        //
        // we still first check observer.active to keep it as the entrance for events. So even if
        // the observer moved to an active state, if we've not received that event, we better not
        // notify for a more predictable notification order.
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        //noinspection unchecked
        observer.mObserver.onChanged((T) mData);
    }

Finally, the onChanged() method of Observer is called to notify the observer. Note that the observer can perceive the life cycle of the component, you can look at the subclass LifecycleBoundObserver of ObserverWrapper.

 

We are starting to analyze from the registered observers in LiveDataActivity:

Follow the observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) method of LiveData:

@MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        owner.getLifecycle().addObserver(wrapper);
    }

The observers passed in are all packaged into the LifecycleBoundObserver type.

Note this line of code:

owner.getLifecycle().addObserver(wrapper);

Obtain the owner object and register the observer object of Lifecycle. Isn't this the Livecycle content mentioned in the previous article?

No wonder it is said that LiveData can perceive the life cycle of components.

So far, the principle of LiveData data update and the principle of life cycle awareness have been fully explained.

 

 

Demo Site: https://github.com/mengzhinan/Lifecycle_LiveData_ViewModel_demo

 

Guess you like

Origin blog.csdn.net/fesdgasdgasdg/article/details/100119688