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线程的).
运行结果如下:
LivaData的基本使用就到这里,是不是很简单啊! 接下来,就让我们来探讨下LiveData的原理吧!!!
======================================================================
我们知道LiveData是通过观察者模式实现的。当数据发送改变的时候,会回调Observer的onChanged(),接下来就让我们深入Observer方法的源码一探究竟
====================================================================
@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