Architecture Components
推出1.0穩(wěn)定版后直接讓SupportActivity
實(shí)現(xiàn)了LifecycleOwner
接口,不需要我們先以前一樣繼承LivecycleActivity
了疮跑,只要是SupportActivity
的子類都是一個(gè)LifecycleOwner
了
public class SupportActivity extends Activity implements LifecycleOwner {
//...
}
幾個(gè)特性
1.如果liveData
中已經(jīng)持有數(shù)據(jù)膝昆,那么 后面添加進(jìn)來(lái)的observer
會(huì)立即觸發(fā)onChange(T t)
方法丸边,把前面的數(shù)據(jù)發(fā)送出去
public interface Observer<T> {
void onChanged(@Nullable T t);
}
2.設(shè)置數(shù)據(jù)的如下兩種方式
protected void postValue(T value) {//....}
protected void setValue(T value) {//....}
setValue(T value)
要求在Ui線程中調(diào)用叠必,如果在子線程調(diào)用會(huì)報(bào)錯(cuò)。在子線程需要更新數(shù)據(jù)的話要調(diào)用postValue(T value)
妹窖,其實(shí)這個(gè)方法實(shí)際上也是調(diào)用了setValue
方法的
protected void postValue(T value) {
//...
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
可以看到挠唆,在最后他將一個(gè)Runnable
調(diào)度到主線程去執(zhí)行,mPostValueRunnable
如下
public void run() {
//...
setValue((T) newValue);
}
postValue(T value)
內(nèi)部切換線程就一定會(huì)增加延遲嘱吗,所以就印證文檔中說(shuō)的,在主線程執(zhí)行如下代碼滔驾,liveData
中的數(shù)據(jù)會(huì)先變?yōu)?code>b然后變?yōu)?code>a
liveData.postValue("a");
liveData.setValue("b");
那么照上面所說(shuō)谒麦,postValue(T value)
有一定延遲的話,短時(shí)間內(nèi)一直觸發(fā)該方法會(huì)不會(huì)造成任務(wù)堆疊呢哆致?我們?cè)賮?lái)看一看源碼
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
看以看出绕德,postTask
為假即 mPendingData != NOT_SET
時(shí)就不會(huì)產(chǎn)生新的調(diào)度了,NOT_SET
就是一個(gè)Object
摊阀,而mPendingData
在初始化時(shí)賦值為NOT_SET
//初始化
private static final Object NOT_SET = new Object();
private volatile Object mPendingData = NOT_SET;
在調(diào)用postValue
后mPendingData
就已經(jīng)不是NOT_SET
了耻蛇,因此如果一直調(diào)用postValue
的話是不會(huì)產(chǎn)生任務(wù)堆疊的。那什么時(shí)候postValue
才重新有效呢胞此?再來(lái)看看被調(diào)度的Runnable
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
mPendingData = NOT_SET;
對(duì)臣咖,就是這時(shí)候postValue(T value)
重新有效了,所以循環(huán)postValue(T value)
的效果是每幾個(gè)調(diào)用只有一個(gè)有效漱牵,上一個(gè)調(diào)度完成才會(huì)產(chǎn)生下一個(gè)夺蛇,并不會(huì)堆疊。