//关闭定时器
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
detailFragment布局
<?xml version="1.0" encoding="utf-8"?>
**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
**深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**
**因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
![img](https://img-blog.csdnimg.cn/img_convert/816747b0b4ca5263c64fc5b4fa6f8371.png)
![img](https://img-blog.csdnimg.cn/img_convert/7a597a926ea8da4dbae895d421c16a45.png)
![img](https://img-blog.csdnimg.cn/img_convert/77cbeb9f59d008c6cbb25798f94dc0c5.png)
![img](https://img-blog.csdnimg.cn/img_convert/e320cb8eac4793ff17ffc393c5c38351.png)
![](https://img-blog.csdnimg.cn/img_convert/0d2da07b2c4c7b109165bb836061a58d.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!**
**由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**
**如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)**
### 写在最后
**很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从哪里入手去学习,对此我整理了一些资料**
如果你熟练掌握以下列出的知识点,相信将会大大增加你通过前两轮技术面试的几率!这些内容都供大家参考,互相学习。
> **①「Android面试真题解析大全」PDF完整高清版+②「Android面试知识体系」学习思维导图压缩包**,最后觉得有帮助、有需要的朋友可以点个赞
>
> ![](https://img-blog.csdnimg.cn/img_convert/b44f9a8710bff76c707a56f059760eb9.webp?x-oss-process=image/format,png)
>
> ![](https://img-blog.csdnimg.cn/img_convert/fec86caf912a89abec3fb78750a27504.webp?x-oss-process=image/format,png)
>
> ![](https://img-blog.csdnimg.cn/img_convert/ff7f0f2b145cc7b652fd522979479825.webp?x-oss-process=image/format,png)
**《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》[点击传送门即可获取!](https://bbs.csdn.net/forums/f76c2498e3b04ae99081eaf6e6cf692c)**
3266341970)]
[外链图片转存中...(img-L97gFHs1-1713266341973)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!**
**由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**
**如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)**
### 写在最后
**很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从哪里入手去学习,对此我整理了一些资料**
如果你熟练掌握以下列出的知识点,相信将会大大增加你通过前两轮技术面试的几率!这些内容都供大家参考,互相学习。
> **①「Android面试真题解析大全」PDF完整高清版+②「Android面试知识体系」学习思维导图压缩包**,最后觉得有帮助、有需要的朋友可以点个赞
>
> [外链图片转存中...(img-BRudv4Jp-1713266341974)]
>
> [外链图片转存中...(img-dMOH0pCU-1713266341975)]
>
> [外链图片转存中...(img-yHkQTXuJ-1713266341976)]
**《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》[点击传送门即可获取!](https://bbs.csdn.net/forums/f76c2498e3b04ae99081eaf6e6cf692c)**