Jetpack(二)LiveData

2022-04-24  本文已影响0人  NIIIICO

LiveData是一种可被观察的数据存储器类。与常规的可观察类不同,LiveData可以观察生命周期,从而使它只有在组件处于活跃生命周期状态时通知观察者。

一、使用

LiveData对象通常存储在ViewModel对象中,并可通过getter方法进行访问,如以下示例中所示:

1、创建LiveData对象
public class NameViewModel extends ViewModel {

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

    public MutableLiveData<String> getCurrentName() {
        if (currentName == null) {
            currentName = new MutableLiveData<String>();
        }
        return currentName;
    }
}
2、添加观察者
public class MainActivity extends AppCompatActivity {
    private NameViewModel model;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 获取ViewModel
        model = new ViewModelProvider(this).get(NameViewModel.class);
        // 添加与生命周期有关的监听
        model.getCurrentName().observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable final String newName) {
                // Update the UI, in this case, a TextView.
                Log.v("AAAAA", "onChange newName:" + newName);
            }
        });
        // 添加与生命周期无关的监听
        model.getCurrentName().observeForever(new Observer<String>() {
            @Override
            public void onChanged(String newName) {
                // Update the UI, in this case, a TextView.
                Log.v("AAAAA", "observeForever onChange newName:" + newName);
            }
        });
    }

    public void onClick(View view) {
        // 改变liveData的值,主线程用set
        model.getCurrentName().setValue("LiMing set");
        // 改变liveData的值,子线程用post
        //model.getCurrentName().postValue("LiMing post");
    }
}

二、源码分析

1、注册

1.1、observe

public abstract class LiveData<T> {
    // 添加观察者
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        // 确保是主线程
        assertMainThread("observe");
        // 获取组件的生命周期状态,如果已经销毁,直接return
        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);
    }
}

class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {}

1.2、observeForever
不同于observe,observeForever不需要关注组件的生命周期,因为缺少相关步骤。

public abstract class LiveData<T> {
    @MainThread
    public void observeForever(@NonNull Observer<? super T> observer) {
        assertMainThread("observeForever");
        AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing instanceof LiveData.LifecycleBoundObserver) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        wrapper.activeStateChanged(true);
    }
}
2、通知

2.1、修改内容

public abstract class LiveData<T> {
    // 设置value
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }


    private final Runnable mPostValueRunnable = new Runnable() {
        @SuppressWarnings("unchecked")
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            setValue((T) newValue);
        }
    };

    // 子线程设置value,通过postValue,到主线程执行,最终还是调用setValue
    protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }
}

2.2、通知

public abstract class LiveData<T> {
    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;
    }

    private void considerNotify(ObserverWrapper observer) {
        if (!observer.mActive) {
            return;
        }
        // 判断声明周期状态
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;

        // 调用监听者的onChanged
        observer.mObserver.onChanged((T) mData);
    }
}

2.3、递归调用处理
由2.2已经知道livedata的分发流程,它内部也对递归调用修改值做了处理;如下代码,最终打印结果为1、2、2。

liveData.observeForever(new Observer<String>() {
    @Override
    public void onChanged(String s) {
        Log.v("AAAAA", "AAAAA:" + s);
        if ("1".equals(s)) {
            liveData.setValue("2");
        }
    }
});

liveData.observeForever(new Observer<String>() {
    @Override
    public void onChanged(String s) {
        Log.v("AAAAA", "AAAAA:" + s);
    }
});

liveData.setValue("1");

下方为执行流程分析:

1、首次setValue(1),进入dispatchingValue();
2、if判断mDispatchingValue == false;不执行代码;
3、mDispatchingValue = true,mDispatchInvalidated == false,进入do while;
4、遍历观察者,通过considerNotify,回调onChanged方法;

5、触发setValue(2),进入dispatchingValue();
6、if判断mDispatchingValue == true,修改mDispatchInvalidated == true,return;
7、回到considerNotify执行完毕,mDispatchInvalidated == true,触发break;
8、由于mDispatchInvalidated == true触发while循环,走第二次分发流程,分发value == 2。
3、粘性事件

3.1、生命周期状态监听
还有一种情况,当没有添加监听时,就设置value,之后再添加监听。包装类LifecycleBoundObserver可以监听组件生命周期,在生命周期变化时,会触发onStateChanged,最终通过dispatchingValue(this)进行分发。

class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
    public void onStateChanged(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {
        Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
        // 当前状态为destroy,移除监听关系
        if (currentState == DESTROYED) {
            removeObserver(mObserver);
            return;
        }

        Lifecycle.State prevState = null;
        while (prevState != currentState) {
            prevState = currentState;
            // 当前为活跃状态,尝试同步数据
            activeStateChanged(shouldBeActive());
            currentState = mOwner.getLifecycle().getCurrentState();
        }
    }

    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);
        }
    }
}

3.2、分发

由于initiator不为null,直接走considerNotify进行分发。

public abstract class LiveData<T> {
void dispatchingValue(@Nullable ObserverWrapper initiator) {
        ...
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                considerNotify(initiator);
                initiator = null;
            } else {
                ...
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }
}

三、注意

protected void postValue(T value) {
    boolean postTask;
    synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;
        mPendingData = value;
    }
    if (!postTask) {
        return;
    }
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
上一篇下一篇

猜你喜欢

热点阅读