Android架构之LiveData组件(1)

}

//关闭定时器

public void stopTiming(){

timer.cancel();

}

}

1234567891011121314151617181920212223242526272829303132333435363738394041

当开始定时器的时候,也就是我们数据资源发生变化的时候,我们需要调用livedata.postvalue方法,通知页面我们数据源已经发生了改变。至于为什么不用livedata.setValue方法,等下我们会说到。

2.接着我们在Activity中创建ViewModel,并监听ViewModel里面currentSecond数据的变化。

public class LiveDataActivity extends AppCompatActivity {



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_live_data);



iniComponent();

}



private void iniComponent() {

//通过ViewModelProvider得到ViewModel

final LiveDataViewModel viewModel = new ViewModelProvider(this).get(LiveDataViewModel.class);



//得到ViewModel中的LiveData

final MutableLiveData liveData = (MutableLiveData) viewModel.getCurrentSecond();



//通过liveData.observer()观察ViewModel中数据的变化

liveData.observe(this, new Observer() {

@Override

public void onChanged(Integer integer) {

//收到回调后更新UI界面

TextView tv = findViewById(R.id.tv_texts);

tv.setText("小鑫啊"+integer);

}

});



//关闭定时器

findViewById(R.id.btnReset).setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

//通过LiveData.setValue()/LiveData.postValue()

//完成对ViewModel中数据的更新

liveData.setValue(0);

//关闭定时器

viewModel.stopTiming();

}

});



//计时开始

viewModel.startTiming();



}

}

1234567891011121314151617181920212223242526272829303132333435363738394041424344







在页面中,通过LiveData.observe()方法对LivaData所包装的数据进行观察。当我们数据源发生变化了(也就是我们想修改LivaData所包装的数据时),就可以通过LiveData.postValue/LiveData.setValue()来完成,然后onChanged方法就会收到我们修改之后的数据,我们就可以对UI进行更改了.



需要注意的是:postValue()方法用在非UI线程中,而setValue()方法用在UI线程中,这就是为什么我们在开始定时器的时候,需要调用postVaule()发送数据了(因为定时器是运行在非UI线程的).



![image](https://img-blog.csdnimg.cn/img_convert/34233f4d394f2759d47ce065f8914d9b.png)



**运行结果如下:**



![image](https://img-blog.csdnimg.cn/img_convert/a160420b3dca4e4c83d49796e04ac432.png)



LivaData的基本使用就到这里,是不是很简单啊! 接下来,就让我们来探讨下LiveData的原理吧!!!



[]( )LiveData的原理

======================================================================



我们知道LiveData是通过观察者模式实现的。当数据发送改变的时候,会回调Observer的onChanged(),接下来就让我们深入Observer方法的源码一探究竟



[]( )observe源码

====================================================================





 @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);

//判断当前wapper已经添加过,如果添加过就直接返回,否则返回null

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;

}

//没有添加过,则添加wrapper

owner.getLifecycle().addObserver(wrapper);

}

123456789101112131415161718192021







从源码可以看出,Observer()方法接收的第一个参数是一个LifecleOwner对象,我们传入的是this,因为this的祖父类实现了这个接口,也正是LifecleOwner对象,LiveData才会具体生命周期感知能力。



首先, 通过owner.getLifecycle().getCurrentState()获取当前页面的状态,如果当前页面被销毁了,就直接返回,也就是说LiveData会自动清除与页面的关联。



[]( )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());

}

1234567891011121314151617181920212223







当调用 LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer),本质是通过 ObserverWrapper将observer包装起来,得以LiveData能对生命周期状态得以进行监听,是通过onStateChanged和shouldBeActive方法



1.  shouldBeActive 这里调用LiftCycle的方法,表达如果当前生命周期的状态为onStart,onResume,onPause时 返回true,也就是说只有这三个状态可以接收数据更新。

2.  onStateChanged 是LifecycleEventObserver接口的方法,当生命周期发送变化的时候会回调它,如果当前生命周期状态是destory,就会直接移除观察者,否则就会调用activeStateChanged(shouldBeActive());方法激活观察者.



方法中的最后一行代码将observer与Activity的生命周期关联在一起。因此,LivaData能够感知页面的生命周期。



[]( )observer方法小结

=======================================================================



1.  判断是否已经销毁,如果当前页面销毁,LiveData自动清除与页面的关联

2.  用LifecycleBoundObserver 对observer进行一个包装

3.  判断当前observer是否已经添加过,添加过就直接返回

4.  将observer方法与Activity的生命周期进行关联



[]( )setValue方法

=====================================================================





 @MainThread

protected void setValue(T value) {

assertMainThread("setValue");

mVersion++;

mData = value;

dispatchingValue(null);

}

1234567







setValue()中,首先 断言是主线程,这里的关键是dispatchingValue(null)方法





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
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值