您好,登錄后才能下訂單哦!
今天小編給大家分享一下Android Jetpack庫之LiveData組件怎么使用的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
在日常安卓開發中,一些耗時的操比如列網絡請求,數據庫讀寫都不能在主線程執行,必須開一條子線程去執行這些耗時操作,但我們往往需要在這些耗時操作執行完畢后更新UI,但安卓不能在子線程進行UI的更新,這時我們只能通過創建一個Handler來切回到主線程進行UI的更新,直到LiveData出現,LiveData是一個可被觀察的數據容器,它將數據包裝起來,使數據成為被觀察者。當數據發生改變時,觀察者能夠及時得到通知。
LiveData是一個數據容器,訂閱視圖的生命周期,在子線程通過postValue()切換到主線程來傳遞數據給觀察者,當視圖是活動的狀態下觀察者即可接受到數據,LiveData是一個典型的觀察者模式。
class MainActivity : AppCompatActivity() { private val mLiveData = MutableLiveData<String>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val binding = ActivityMainBinding.inflate(LayoutInflater.from(baseContext)) setContentView(binding.root) mLiveData.observe(this, { binding.tvContent.text = it }) Thread(BackgroundThread(mLiveData)).start() } private class BackgroundThread(liveData: MutableLiveData<String>) : Runnable { private val mLive = WeakReference(liveData) override fun run() { mLive.apply { get()?.apply { postValue("hello LiveData") } } } } }
@MainThread public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) { //1,判斷是否在主線程 assertMainThread("observe"); if (owner.getLifecycle().getCurrentState() == DESTROYED) { // ignore return; } //2,通過owner,observer來構建一個LifecycleBoundObserver LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer); //3,把observer存放到mObservers中 ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper); //4,如果existing不為空代表觀察者已經存在并且已經綁定了生命周期,拋一個Exception來提示 if (existing != null && !existing.isAttachedTo(owner)) { throw new IllegalArgumentException("Cannot add the same observer" + " with different lifecycles"); } if (existing != null) { return; } //5,調用Lifecycle的addObserver()方法來訂閱生命周期 owner.getLifecycle().addObserver(wrapper); }
1,先判斷當前訂閱數據這個操作是否是在主線程中執行,否則的話拋一個Exception
2,把owner,observer傳入到LifecycleBoundObserver構建出一個LifecycleBoundObserver對象
3,調用mObservers.putIfAbsent()方法把觀察者放到觀察者集合中,mObservers是SafeIterableMap類型的集合類似Map,但它是通過鏈表的方式來實現Map接口,SafeIterableMap.putIfAbsent()方法與Map.put()方法不一樣,如果根據key獲取的value不為null,就將當前的value返回,如果為null,就將當前的鍵值對存儲起來,然后返回一個null
4,existing不為null,代表Observer存在,就拋一個Exception來提示開發者:無法添加具有不同生命周期的同一觀察者
5,existing為null,代表observer不存在,添加觀察者來觀察生命周期擁有者的生命周期,
當我們的視圖的生命周期發生改變,LifecycleBoundObserver的onStateChange()方法就會被調用
protected void postValue(T value) { boolean postTask; //判斷當前是否正在下發數據 synchronized (mDataLock) { postTask = mPendingData == NOT_SET; mPendingData = value; } //如果正在下發數據則繼續下發數據 if (!postTask) { return; } //構建Handler并關聯主線程的Looper,回到主線程執行run方法中的邏輯 ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable); } private final Runnable mPostValueRunnable = new Runnable() { @Override public void run() { Object newValue; synchronized (mDataLock) { newValue = mPendingData; mPendingData = NOT_SET; } //在主線程中調用setValue來執行數據下發邏輯 //noinspection unchecked setValue((T) newValue); } };
當調用postValue()方法是通過構建一個Handler并關聯主線程的Looper來post一個Runnable來回到主線程執行run方法里面的邏輯,而mPostValueRunnable的run()方法則調用了setValue()方法來實現數據的發送
@MainThread protected void setValue(T value) { assertMainThread("setValue"); mVersion++; mData = value; dispatchingValue(null); } void dispatchingValue(@Nullable ObserverWrapper initiator) { //1,判斷當前是正在下發數據 if (mDispatchingValue) { mDispatchInvalidated = true; return; } mDispatchingValue = true; do { mDispatchInvalidated = false; //2,如果initiator不為空直接給initiator發送數據更新通知 if (initiator != null) { considerNotify(initiator); initiator = null; } else { /,3,否則遍歷所有observer for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =mObservers.iteratorWithAdditions(); iterator.hasNext(); ) { /4,發送數據更新通知 considerNotify(iterator.next().getValue()); if (mDispatchInvalidated) { break; } } } } while (mDispatchInvalidated); mDispatchingValue = false; } private void considerNotify(ObserverWrapper observer) { 5,如果當前observer不是活動狀態,不下發數據 if (!observer.mActive) { return; } 6,如果當前observer的狀態至少不是started狀態(可見狀態),resumed比started高一個級別(可觸摸狀態)則不下發數據 if (!observer.shouldBeActive()) { observer.activeStateChanged(false); return; } 7,判斷數據版本號 如果當前observer的數據是最新的 則不下發數據 if (observer.mLastVersion >= mVersion) { return; } 8,記錄最新數據版本號 observer.mLastVersion = mVersion; 9,通知數據更新 observer.mObserver.onChanged((T) mData); } @Override boolean shouldBeActive() { 判斷當前狀態是否>=STARTED return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED); }
1,檢查當前是否在主線程
2, 每次調用setValue()方法版本號(mVersion)都進行累加
3,把需要新數據賦值給mData
4,調用dispatchingValue來執行數據下發
5,如果initiator不為null則直接給這個觀察者下發數據更新通知
6,否則遍歷所有的觀察者,逐個下發數據更新通知
7,判斷當前的observer是否為活動狀態,不是活動狀態不下發數據,這也就是為什么我們界面不可見時數據不會更新的原因(onStop狀態)
8,判斷當前的observer是否是resumed狀態,不是resumed狀態不下發數據,這就是為什么當我們的頁面可見但不可觸摸時數據不更新的原因(onPause狀態)
9,比對數據版本號,如果當前observer的數據是最新數據則不需要下發
10,記錄數據版本號并通知observer數據更新,回調observer的onChanged()方法
@Override public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) { 1,如果當前的狀態為destroyed就移除observer if (mOwner.getLifecycle().getCurrentState() == DESTROYED) { removeObserver(mObserver); return; } 2,更新狀態并下發數據 activeStateChanged(shouldBeActive()); } void activeStateChanged(boolean newActive) { 3,如果新狀態和當前狀態一致的話不需要更新 if (newActive == mActive) { return; } 4,記錄新狀態 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(); } 5,如果是活動狀態 下發數據 if (mActive) { dispatchingValue(this); } }
在訂閱數據那一刻(即調用LiveData.observer())就構建了一個LifecycleBoundObserver并且讓LifecycleBoundObserver訂閱了頁面生命周期,所以當頁面的生命周期發生改變,LifecycleBoundObserver的onStateChanged()方法都會被調用
1,如果當前頁面的狀態為destroyed(即銷毀狀態),則移除觀察者
2,更新狀態并下發數據
3,判斷當前observer的狀態跟新狀態是否一致,如果時是則不需要更新狀態以及數據
4,記錄當前observer的狀態
5,調用dispatchingValue()并傳入當前observer,執行準確下發數據業務
以上就是“Android Jetpack庫之LiveData組件怎么使用”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。