Android JetPack学习笔记之LiveData
Android JetPack学习笔记之LiveData
- 前言
- LiveData
- LiveData类图分析
- LiveData源码分析
- 1.添加观察者
- observe
- observeForever
- 2.LiveData.setValue/postValue
- 2.组件的状态改变
前言
Jetpack 是 Android 软件组件的集合,使您可以更轻松地开发出色的 Android 应用。这些组件可帮助您遵循最佳做法、让您摆脱编写样板代码的工作并简化复杂任务,以便您将精力集中放在所需的代码上。
最近有空边学习边把学习笔记做了。巩固知识,输入输出,强化学习,如有不对望指出,感谢。
(以下是对官方代码文档的翻译和自己的部分见解)
如果引用JetPack库
implementation 'android.arch.lifecycle:extensions:1.1.1'
LiveData
LiveData是一个可以在给定Lifecycle内观察到的数据持有者类。
这就意味着一个(lifecycleOwner)生命周期持有者添加了一个
观察者(observer),并且这个观察者(observer)只有当成对的LifecycleOwner处于活动状态时,才会通知观察者(observer)有关打包数据的修改。如果LifecycleOwner的状态Lifecycle.State== STARTED 或者 Lifecycle.State ==RESUMED的话,该LifecycleOwner是处于活动的。观察者通过observeforever(observer)被视为始终处于活动状态,因此将始终收到修改的通知。对于这些observers,你需要手动调用removeObserver来移除监听。
1.一个Lifecycle已订阅了一个Observer,如果Lifecycle的状态转变成Lifecycle.State==DESTROYED时那么Observer将自动被移除。这可以Activity/Fragment
帮助他们安全的观察LiveData并且不用担心内存泄漏,当他们销毁时将立即取消订阅
2. 另外,LiveData有onActive()(活动中)和onInactive()(不活动)方法用来获得Observer的活动状态从0到1发生改变。这允许LiveData在不需要一些Observers积极观察时释放一些繁重的资源。
3.这个类被设计用于持有ViewModel的单独数据字段,但也可以用于你的应用/解耦方式 中不同models的数据分享的
4. ViewModel只负责管理UI的数据,它不应该直接访问你的视图层次和持有你的Activity/Fragment的引用。(例如:不把视图对象或者Activity/Fragment的Context作为对象传入到ViewModel中。避免内存泄漏)
LiveData类图分析
LiveData源码分析
LiveData涉及到三个时序过程
1.Fragment/Activity通过LiveData.observe()方法添加观察者。
2.当调用LiveData.setValue/postValue方法时,触发onChange方法。通知观察者数据更新
3.当Fragment/Activity的活动状态改变时也会触发onChange方法
1.添加观察者
添加观察者有2中方式observe和observeForever
observe
@MainThread public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) { if (owner.getLifecycle().getCurrentState() == DESTROYED) { // 判断所属观察持有者(owner)的生命周期状态是否销毁 return; } LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer); //将owner和observer观察者加入SafeIterableMap中 ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper); if (existing != null && !existing.isAttachedTo(owner)) { //确保同一个观察者绑定同一个lifecycle throw new IllegalArgumentException("Cannot add the same observer" + " with different lifecycles"); } if (existing != null) { return; } // owner.getLifecycle().addObserver(wrapper); }
observeForever
@MainThread public void observeForever(@NonNull Observer<T> observer) { //AlwaysActiveObserver 的shouldBeActive()始终返回的true, //使得Fragment/Activity的始终能收到回调通知 AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer); ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper); if (existing != null && existing instanceof LiveData.LifecycleBoundObserver) { throw new IllegalArgumentException("Cannot add the same observer" + " with different lifecycles"); } if (existing != null) { return; } wrapper.activeStateChanged(true); }
2.LiveData.setValue/postValue
protected void postValue(T value) { boolean postTask; synchronized (mDataLock) { //mPendingData声明为volatile 保证原子性 postTask = mPendingData == NOT_SET; mPendingData = value; } if (!postTask) { return; } ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);} private final Runnable mPostValueRunnable = new Runnable() { @Override public void run() { Object newValue; synchronized (mDataLock) { newValue = mPendingData; mPendingData = NOT_SET; } //noinspection unchecked setValue((T) newValue); } };
@MainThread protected void setValue(T value) { //判断当前是否在主线程中 assertMainThread("setValue"); mVersion++; mData = value; dispatchingValue(null); }
注意:postValue在时间上晚于setValue.
2.组件的状态改变
@Override public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) { if (mOwner.getLifecycle().getCurrentState() == DESTROYED) { removeObserver(mObserver); return; } //lifecycle状态变化时会发起通知 activeStateChanged(shouldBeActive()); } void activeStateChanged(boolean newActive) { if (newActive == mActive) { return; } // immediately set active state, so we'd never dispatch anything to inactive // owner mActive = newActive; boolean wasInactive = LiveData.this.mActiveCount == 0; LiveData.this.mActiveCount += mActive ? 1 : -1; if (wasInactive && mActive) { onActive(); } if (LiveData.this.mActiveCount == 0 && !mActive) { onInactive(); } if (mActive) { dispatchingValue(this); } } 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); }//遍历所有的观察者,调用onChange方法 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; }
参考文章:
【链接】Java并发编程:volatile关键字解析
https://www.cnblogs.com/dolphin0520/p/3920373.html
SafeIterableMap解析
https://blog.csdn.net/llew2011/article/details/85222413
更多相关文章
- Android下的数据储存方式(三)
- android中将数据写入手机内存和sdcard中的文件
- Android settings.db数据库中添加一条新的默认配置项
- 72、android状态栏一体化,状态栏改变颜色
- Android之解析Json数据
- Android控件ToggleButton多状态按钮使用详解
- Notification中Intent携带数据重复问题
- Android如何实现5.0以上图片沉浸式状态栏