Jetpack之LiveData原理分析

Jetpack之LiveData原理分析

一、LiveData的基本使用

//创建一个LiveData对象
private MutableLiveData<String> currentName=new MutableLiveData<>();
//创建一个观察者,currentName的value改变时会回调到onChanged方法,获取到改变后的值用一个textView来显示改变的内容
Observer observer=new Observer<String>(){
	@Override
	public void onChanged(String s) {
		nameTextView.setText(s);
	}
};
//订阅
currentName.observe(MainActivity.this,observer);
//点击按钮时setValue
btn.setOnClickListener(new View.OnClickListener(){
	@Override
	public void onClick(View v) {
		String anotherName="test"+(i++);
		currentName.setValue(anotherName);
	}
});

二、LiveData的工作原理

MutableLiveData的observe方法里需要传递两个参数,第一个参数是实现了LifecycleOwner接口的具有生命周期的被观察者对象,AppCompatActivity的父类ComponentActivity实现了LifecycleOwner接口,所以第一个参数可以设置为Activity自身。第二个参数是观察者Observer。
LiveData的observe源码如下:

private SafeIterableMap<Observer<? super T>, ObserverWrapper> 
mObservers =new SafeIterableMap<>();
@MainThread
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方法中把被观察者和观察者封装到了LifecycleBoundObserver中,并以被观察者为key,封装后的wrapper为value放到了一个具有安全迭代器的SafeIterableMap中,接下来看LifecycleBoundObserver源码:

class LifecycleBoundObserver extends ObserverWrapper implements 
LifecycleEventObserver {
    @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(@NonNull LifecycleOwner source,
                @NonNull 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);
    }
}

public interface LifecycleEventObserver extends 
	LifecycleObserver {
    void onStateChanged(@NonNull LifecycleOwner source, 
    	@NonNull Lifecycle.Event event);
}

LifecycleBoundObserver本身是实现了LifecycleObserver接口,可以观察到activity的生命周期的变化,当activity生命周期发生变化时会经过反射执行onStateChanged方法,onStateChanged中判断activity是否已销毁,销毁时移除此观察者,避免内存泄漏。

接下来看currentName.setValue方法中做了什么事情:

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

void dispatchingValue(@Nullable ObserverWrapper initiator) {
	if (mDispatchingValue) {
    	mDispatchInvalidated = true;
        return;
    }
    mDispatchingValue = true;
    do {
       mDispatchInvalidated = false;
       if (initiator != null) {
           //TODO 1
          considerNotify(initiator);
          initiator = null;
       } else {
           //TODO 2
           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) {
    //判断当前activity是否处于活动状态
	if (!observer.mActive) {
        return;
    }
    //判断当前activity是否处于前台显示状态
    if (!observer.shouldBeActive()) {
        //TODO 3
        observer.activeStateChanged(false);
        return;
    }
    //判断mLastVersion是否发生变化
    //TODO 6
    if (observer.mLastVersion >= mVersion) {
       return;
    }
    //TODO 7
    observer.mLastVersion = mVersion;
    observer.mObserver.onChanged((T) mData);
}

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;
        }
        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) {
            //TODO 4
            dispatchingValue(this);
        }
    }
}

当setValue时最终会执行到dispatchingValue(null),此时传了null,必然会执行TODO 2的位置获取mObservers的迭代器,for循环遍历获取所有的观察者,把观察者传递到considerNotify方法。

当观察者ObserverWrapper绑定的activity处于后台状态时会执行TODO 3位置,调用activeStateChanged方法,在activeStateChanged方法中执行TODO 4位置时又会调用dispatchingValue方法,这样循环调用来监听被绑定activity是否被切回前台状态,当切回前台状态时才会在activeStateChanged方法中继续执行,最终调用mObserver的onChange方法更新UI。

当setValue时TODO 5位置mVersion++,当判定观察者绑定activity处于前台位置时会执行到TODO 6位置时,此时observer.mLastVersion小于mVersion,会往下执行到达TODO 7位置时把observer.mLastVersion和mVersion同步,避免重复调用mObserver的onChange方法。

considerNotify方法中的三个判段保证在value发生变化时只有与处于前台并且没有更新过数据的activity绑定的观察者mObserver的onChanged方法会执行,实现当后台activity切回到前台时只获取到最后一次更新的内容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值