当前位置:网站首页>Read livedata sticky events

Read livedata sticky events

2022-06-22 01:23:00 Silent Pinot trough

Article to read LiveData The sticky events of

Preface

Put it in a more general way , Is to send data first , Post subscription , Data can also be received .

[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-klZR6QTN-1655823049309)(/Users/wyl/Documents/ Blog / article / picture /tutieshi_640x360_2s.gif)]

This is actually livedata A feature of , However, it has brought great inconvenience to our daily use , And it doesn't provide API To remove sticky events , This is really not very friendly .

Next , Just bring us to uncover the secret LiveData Principle of viscous event .

A lot of source code is coming from the front , In case of any discomfort , You can jump directly to the summary .

principle

First we start by sending a message

liveData.postValue(" page 1  Message sent ")

There are two ways to send messages :setValue and postValue

setValue Can only be used on the main thread ,postValue Can be used in any thread , When it is called , adopt handler Switch to the main thread , Call again setValue

    @MainThread
    protected void setValue(T value) {
    
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }

Here is a mVersion Pay attention to , We'll use that later . And then through dispatchingValue Method to distribute messages .

    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<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
    
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
    
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

In this way , It is mainly about whether the observer of parameter transmission is empty , If it's not empty , Then distribute the message to this observer , If it is empty , The observer will be traversed from the observer set , distributed . ad locum , We mainly look at considerNotify Method .

    private void considerNotify(ObserverWrapper observer) {
    
        ...............
        if (observer.mLastVersion >= mVersion) {
    
            return;
        }
        observer.mLastVersion = mVersion;
        observer.mObserver.onChanged((T) mData);
    }

We mentioned earlier mVersion It's used here , and mLastVersion Made a comparison , We will explain this in the next step .

This is the whole process of sending messages , It's very simple , But it's not enough to see the whole picture , Next we analyze another step , monitor .

liveData.observe(this) {
    
            Log.e("TAG", "onCreate: ")
            tv.setText(" Monitored messages :$it")
        }
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    
        assertMainThread("observe");
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
    
            // ignore
            return;
        }
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        ............
        owner.getLifecycle().addObserver(wrapper);
    }

ad locum , Mainly for our owner and observer Made a layer of packing , And then let lifecycle It was monitored . Then we'll see What's packed

    class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
    
        @NonNull
        final LifecycleOwner mOwner;

        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
    
            super(observer);
            mOwner = owner;
        }
       .........
        @Override
        public void onStateChanged(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event) {
    
            Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
            if (currentState == DESTROYED) {
    
                removeObserver(mObserver);
                return;
            }
            Lifecycle.State prevState = null;
            while (prevState != currentState) {
    
                prevState = currentState;
                activeStateChanged(shouldBeActive());
                currentState = mOwner.getLifecycle().getCurrentState();
            }
        }
        ............
    }

You can see LifecycleBoundObserver Inherited ObserverWrapper , Realized LifecycleEventObserver Interface .

LifecycleEventObserver Interface Mainly when lifecycle When the state changes, it will sense , And call back .

Then we mainly look at the parent class ObserverWrapper :

    private abstract class ObserverWrapper {
    
        final Observer<? super T> mObserver;
        boolean mActive;
        int mLastVersion = START_VERSION;

        ObserverWrapper(Observer<? super T> observer) {
    
            mObserver = observer;
        }
        ............
        void activeStateChanged(boolean newActive) {
    
            if (newActive == mActive) {
    
                return;
            }
            // immediately set active state, so we'd never dispatch anything to inactive
            // owner
            mActive = newActive;
            changeActiveCounter(mActive ? 1 : -1);
            if (mActive) {
    
                dispatchingValue(this);
            }
        }
    }

Did you see a familiar face , This is our last step Mentioned mLastVersion , It is defined here , And the default is -1; This will be run through later , First understand its source .

Next , Let's continue the process first , still LifecycleBoundObserver Class , When the state changes , Would call onStateChanged Method

  @Override
        public void onStateChanged(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event) {
    
            Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
            if (currentState == DESTROYED) {
    
                removeObserver(mObserver);
                return;
            }
            Lifecycle.State prevState = null;
            while (prevState != currentState) {
    
                prevState = currentState;
                activeStateChanged(shouldBeActive());
                currentState = mOwner.getLifecycle().getCurrentState();
            }
        }

When the active state changes , Meeting call activeStateChanged :

void activeStateChanged(boolean newActive) {
    
    if (newActive == mActive) {
    
        return;
    }
    mActive = newActive;
    changeActiveCounter(mActive ? 1 : -1);
    if (mActive) {
    
        dispatchingValue(this);
    }
}

When the state is active , Would call dispatchingValue Data distribution , The distribution we used above is to traverse all observers for data distribution , This time, only the current observer will be distributed .

summary

Next, let's continue :

First send the data postValue , The number of times will make mVersion++ operation , Then traverse the observer for distribution .

Then listen , While listening , Will use LifecycleBoundObserver Pack the observer , In this operation ,LifecycleBoundObserver Parent class of ObserverWrapper Defined mLastVersion by -1 . When the data is finally distributed ,mLastVersion Less than mVersion Of , So it was not intercepted , Then the data is distributed .

And then there's the sticky event .

 Insert picture description here

There are many solutions for sticky events now , I won't elaborate here , You can refer to this article :

https://www.jianshu.com/p/d0244c4c7cc9

原网站

版权声明
本文为[Silent Pinot trough]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/173/202206212331478098.html