Android架构之LiveData组件

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的原理吧!!!



[](https://docs.qq.com/doc/DSkNLaERkbnFoS0ZF)LiveData的原理

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



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



[](https://docs.qq.com/doc/DSkNLaERkbnFoS0ZF)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会自动清除与页面的关联。



[](https://docs.qq.com/doc/DSkNLaERkbnFoS0ZF)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能够感知页面的生命周期。



[](https://docs.qq.com/doc/DSkNLaERkbnFoS0ZF)observer方法小结

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



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

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

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

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



[](https://docs.qq.com/doc/DSkNLaERkbnFoS0ZF)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

detailFragment布局

<?xml version="1.0" encoding="utf-8"?>











1234567891011121314151617







[](https://docs.qq.com/doc/DSkNLaERkbnFoS0ZF)detailFragment代码

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





@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

View view =inflater.inflate(R.layout.fragment_detail, container, false);

final TextView textView = view.findViewById(R.id.tv_text1);

SharedViewModel model = new ViewModelProvider(getActivity()).get(SharedViewModel.class);

MutableLiveData mutableLiveData = (MutableLiveData) model.getContent();

//对LiveData进行监听

mutableLiveData.observe(getActivity(), new Observer() {

@Override

public void onChanged(String s) {

//显示在UI上

textView.setText(s);

}

});



return view;

}

123456789101112131415161718







[](https://docs.qq.com/doc/DSkNLaERkbnFoS0ZF)Activity布局

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





<?xml version="1.0" encoding="utf-8"?>

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值