LiveData的使用會結合Lifecycles和ViewModel一塊兒使用,不瞭解兩者的,建議先看這兩篇文章: Android Jetpack之ViewModel源碼分析 Android Jetpack之Lifecycles源碼分析java
LiveData 是保存數據對象的類,經過註冊監聽器Observer 監聽數據的變化。LiveData最大的優點:LiveData 是感知Activity、Fragment等生命週期的組件,Observer 能夠指定監聽的生命週期(Lifecycle)對象。當 Observer 的 Lifecycle 對象處於 STARTED 或者 RESUMED 狀態的時候, LiveData 處於活動狀態,在活動狀態下數據變化會通知到相應的Observer。當相應Lifecycle對象的狀態改變爲DESTROYED時移除觀察者,因此避免形成內存泄漏。固然也能夠不和Lifecycles綁定,使用observeForever(Observer)方法註冊一個沒有關聯生命週期全部者對象的觀察者,觀察者老是處於活動狀態,所以數據變化事件老是會被通知到,能夠經過調用removeObserver(Observer) 刪除observer。 官網指導連接Android jetpack之LiveDataandroid
建立一個ViewModel類,裏面有LiveData實例來保存數據。使用ViewModel是爲了在屏幕旋轉等操做下時能夠恢復現場數據。bash
class MyLiveDataViewModel : ViewModel(){
var liveData: MutableLiveData<String>?= null
get() {
if(field == null){
field = MutableLiveData()
}
return field
}
}
複製代碼
(1)代碼1: 建立LiveDataActivity實現LifecycleOwner接口,爲了Observer和組件的生命週期綁定。 (2)代碼2: 獲取定義的MyLiveDataViewModel實例 (3)代碼3: 建立定義onChanged()方法的Observer對象,在數據變化時更新UI頁面。 (4)代碼4: LiveData訂閱觀察,將LiveData和Lifecycles、Observer綁定, (5)代碼5: LiveData設置新數據,通知觀察者更新數據。能夠在子線程中執行。 完整代碼以下:數據結構
//代碼1
class LiveDataActivity : AppCompatActivity(),LifecycleOwner{
private lateinit var lifecycleRegistroy: LifecycleRegistry
private var coun : Int by Delegates.notNull<Int>()
override fun getLifecycle(): Lifecycle {
return lifecycleRegistroy
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_live_data)
lifecycleRegistroy = LifecycleRegistry(this)
coun = 0
//代碼2
var viewModel = ViewModelProviders.of(this).get(MyLiveDataViewModel::class.java)
//代碼3
val observer = Observer<String>{
text.text = it
}
button.setOnClickListener {
//代碼5
viewModel.liveData?.postValue("changed !!!!"+coun++)}
//代碼4
viewModel.liveData?.observe(this,observer)
}
}
複製代碼
在Activity中經過添加observe方法將Lifecycles和Observer綁定起來。下面咱們來分析該方法。該方法有兩個參數:併發
下面來分析observe方法內部的實現原理:app
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);
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);
}
複製代碼
經過observe.observer的分析咱們知道,內部主要是用了LifecycleBoundObserver類,下面分析該類ide
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
複製代碼
LifecycleBoundObserver 繼承自 ObserverWrapper而且在onStateChanged中調用了activeStateChanged的方法,下面來分析一下ObserverWrapper類。函數
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
abstract boolean shouldBeActive();
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
void detachObserver() {
}
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); } } } 複製代碼
使用observeForever(Observer)方法註冊一個沒有關聯生命週期全部者對象的觀察者,觀察者老是處於活動狀態,所以數據變化事件老是會被通知到。下面咱們來看一下其中的原理:oop
public void observeForever(@NonNull Observer<? super T> observer) {
assertMainThread("observeForever");
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);
}
複製代碼
在observeForever使用的AlwaysActiveObserver該類不一樣於LifecycleBoundObserver類,沒有實現GenericLifecycleObserver接口,因此不能感激組件的生命週期變化,而且其實該方法,也沒有LifecycleOwner的形參。在AlwaysActiveObserver 的類內部的shouldBeActive方法用於返回ture,而且在observeForever內部將ObserverWrapper.mActive設置爲true,也就是標明永遠是處於活躍狀態,因此Observer是一直能夠觀察數據變化的。源碼分析
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
複製代碼
在Activity中,經過postValue或者setValue改變LivwData的數據,在經過Observer,觀察LIveData數據的變化。經過上面的分析,咱們已經知道了Observer是如何和組件的生命週期綁定起來的,下面咱們就分析一下,LiveData的數據更新是如何通知到Observer 的。
先來分析一下setValue()方法,setValue()必須在主線程中調用,不然會報錯,而postValue則沒有這個檢查。看到有無post的區別,第一反應就是是invalidate和postInvalidate的區別。
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
複製代碼
下面在分析一下dispatchingValue方法。
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
//代碼1
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;
}
// 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);
}
複製代碼
postValue方法能夠在非主線程中更新數據。主要是經過ArchTaskExecutor和DefaultTaskExecutor切換到主線程中。而後回調到Runnable方法中,在Runnable的run方法其實也是調用了setValue方法來實現通知觀察者更新數據的邏輯的。
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
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);
}
};
複製代碼
ArchTaskExecutor是單例模式。繼承自TaskExecutor。
public static ArchTaskExecutor getInstance() {
if (sInstance != null) {
return sInstance;
}
synchronized (ArchTaskExecutor.class) {
if (sInstance == null) {
sInstance = new ArchTaskExecutor();
}
}
return sInstance;
}
複製代碼
當調用postToMainThread切換線程是,內部其實是執行了DefaultTaskExecutor類的postToMainThread方法。
public void postToMainThread(Runnable runnable) {
mDelegate.postToMainThread(runnable);
}
複製代碼
DefaultTaskExecutor類的postToMainThread內部經過Handler實現線程的切換。
@Override
public void postToMainThread(Runnable runnable) {
if (mMainHandler == null) {
synchronized (mLock) {
if (mMainHandler == null) {
mMainHandler = new Handler(Looper.getMainLooper());
}
}
}
//noinspection ConstantConditions
mMainHandler.post(runnable);
}
複製代碼
LiveData 支持簡單的數據變換。
使用 Transformation 的好處:若是 Lifecycle 處於未激活狀態,則轉換函數也一樣不會執行。 map實例:
class MyLiveDataViewModel : ViewModel(){
var liveData: MutableLiveData<User> = MutableLiveData()
get() {
return field
}
}
class User(val name: String,val lastName: String)
class LiveDataActivity : AppCompatActivity(),LifecycleOwner{
private lateinit var lifecycleRegistroy: LifecycleRegistry
override fun getLifecycle(): Lifecycle {
return lifecycleRegistroy
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_live_data)
lifecycleRegistroy = LifecycleRegistry(this)
var viewModel = ViewModelProviders.of(this).get(MyLiveDataViewModel::class.java)
val observer = Observer<String>{
text.text = it
}
button.setOnClickListener {
var user = User("android","jectpack")
viewModel.liveData.postValue(user)}
val userLivaData: LiveData<User> = viewModel.liveData
val nameLiveData: LiveData<String> = Transformations.map(userLivaData){
it.name + it.lastName
}
nameLiveData.observe(this,observer)
}
}
複製代碼
switchMap實例:
class LiveDataActivity : AppCompatActivity(),LifecycleOwner{
private lateinit var lifecycleRegistroy: LifecycleRegistry
override fun getLifecycle(): Lifecycle {
return lifecycleRegistroy
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_live_data)
lifecycleRegistroy = LifecycleRegistry(this)
var viewModel = ViewModelProviders.of(this).get(MyLiveDataViewModel::class.java)
val observer = Observer<String>{
text.text = it
}
button.setOnClickListener {
var user = User("android","jectpack")
viewModel.liveData.postValue(user)}
val userLivaData: LiveData<User> = viewModel.liveData
val nameLiveData: LiveData<String> = Transformations.switchMap(userLivaData){
getUserName(it)
}
nameLiveData.observe(this,observer)
}
private fun getUserName(user: User): LiveData<String> {
val liveData: MutableLiveData<String> = MutableLiveData<String>()
liveData.value = user.name +" switch map " + user.lastName
return liveData
}
}
複製代碼
MediatorLiveData的做用是合併幾個流到一個流中。 實例代碼:
class LiveDataActivity : AppCompatActivity(),LifecycleOwner{
private lateinit var lifecycleRegistroy: LifecycleRegistry
override fun getLifecycle(): Lifecycle {
return lifecycleRegistroy
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_live_data)
lifecycleRegistroy = LifecycleRegistry(this)
var viewModel = ViewModelProviders.of(this).get(MyLiveDataViewModel::class.java)
val observer = Observer<String>{
text.text = it
}
button.setOnClickListener {
var user = User("android","jectpack")
viewModel.liveData.postValue(user)}
val userLivaData: LiveData<User> = viewModel.liveData
val nameLiveData: LiveData<String> = Transformations.switchMap(userLivaData){
getUserName(it)
}
var mediatorLiveData: MediatorLiveData<String> = MediatorLiveData()
mediatorLiveData.addSource(userLivaData){
mediatorLiveData.value = "first source "
}
mediatorLiveData.addSource(nameLiveData){
mediatorLiveData.value = it + " second source"
}
mediatorLiveData.observe(this,observer)
}
private fun getUserName(user: User): LiveData<String> {
val liveData: MutableLiveData<String> = MutableLiveData<String>()
liveData.value = " "
return liveData
}
}
複製代碼