从非活跃状态变为活跃状态时,回调方法会立即接收到最新的数据 当设备切横竖屏,会重建Activity生命周期,它也会立即接收最新的可用数据。...下面代码讲解 抽象类,无法直接new 2、什么是MutableLiveData MutableLiveData的父类是LiveData 用法和LiveData类似,也是在注册观察者回调里查看更新数据 可变...super.setValue(value); } } 可以看到在MutableLiveData包裹的有setValue,postValue方法 当然我们也可以让它不对外暴露setValue,...} //在外面只能通过这种方式去更新 public void setmStr(String s) { mStr.setValue(s); } } 7、其他方法...postValue() postValue的特性如下: 1.此方法可以在其他线程中调用 2.如果在主线程执行发布的任务之前多次调用此方法,则仅将分配最后一个值。
首语 ViewModel 以注重生命周期的方式存储和管理界面相关的数据,当数据发生变化时,可通过接口的方式通知页面,但是有很多数据要通知时,需要定义大量的接口显得十分冗余,为此,Jetpack提供了LiveData...LiveData 将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化。 数据始终保持最新状态 如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。...通过LiveData+ViewModel 完成一个计数器的例子。...(value == null) { value = new MutableLiveData(); value.setValue(0);...LiveData.observe()对LiveData所包装的数据进行观察,我们也可以通过Livedata的postValue()或Livedata的setValue()来完成修改数据,postValue
LiveData对象一旦连接到系统服务,任何需要该资源的Observer都只需观察这个LiveData对象。 如何使用LiveData? 1.创建一个LiveData的实例来保存特定类型的数据。...一个 LiveData对象通常存储在ViewModel对象中,并通过getter方法访问,如以下示例所示: public class NameViewModel extends ViewModel {...MutableLiveData类暴露公用的setValue(T)和postValue(T)方法,如果需要编辑存储在LiveData对象中的值,必须使用这两个方法。...注意:必须要从主线程调用setValue(T) 方法来更新LiveData 对象. 如果代码在工作线程中执行, 你可以使用postValue(T) 方法来更新LiveData对象....LiveData只在他们至少一个处于可见和活跃状态时才连接到系统服务。
所以我们就要做到当计数的数字发生改变时,通知TextView便于TextView重新显示,如果矬一点,可能会想到将View传递到ViewModel中,让ViewModel持有View的引用,这种方式确实可以实现需求... mCount = new MutableLiveData(); public Main3ActivityViewModel(int count) { this.mCount.setValue...(count); } } LiveData类型的变量我们通过set和get去赋值和取值 现在计数的数字已经是LiveData类型的了,那么我们如何在数据变化的时候通知textView呢 我们只需要在... mCount = new MutableLiveData(); public void add() { mCount.setValue(mCount.getValue...= new MutableLiveData(); public void setScore(int score) { this.score.setValue(score); } 使用switchMap
接着走到onResume(),也setValue了,同样是活跃状态,所以立刻回调onChanged,打印onChanged: onResume 按Home键时,onPause()中setValue,活跃状态...onStop()执行时已经变为非活跃状态,此时setValue不会立即回调onChanged方法。...再点开时,走到onStart()变为活跃时,onChanged被调用,但value被onStart()中setValue的value覆盖,所以打印的是onChanged: onStart。...也就是说,只有当 存在活跃的观察者(LifecycleOwner)时 才会连接到 股价更新服务 监听股价变化。...到这里观察者模式完整的实现逻辑就梳理清晰了:LivaData通过observe()添加 与LifecycleOwner绑定的观察者;观察者变为活跃时回调最新的数据;使用setValue()、postValue
LiveData 默认是支持粘性消息的(关于什么是粘性消息,请移步我的另一篇文章:LiveData 的正确使用姿势以及反模式 ),如何通过 LiveData 来实现非粘性消息呢,本文将在官博的基础上,...null } } 复制代码 缺陷: 需要在 observer 中增加一些逻辑判断代码,这不符合简洁的 MVVM 模式(不应该在 View 层做过多的逻辑处理) 需要手动重置,不够优雅,一旦忘记重置就容易引发问题...Void, to make calls cleaner. */ @MainThread fun call() { setValue(null) }...() 之后 onChange() 只会回调一次,因此,如果有多个 observer 的话,也只有一个才能收到回调,而且无法保证哪一个 observer 被回调(每个 observer 生命周期不一样,observe...peek() 可返回已经被消费的数据 缺陷: 和姿势二一样,observe() 之前的数据还是会被监听到,没有解决问题 虽然可以添加多个 observers 且使用 peek() 来获取数据,但是还是无法实现多个
LifecycleBoundleObserver:继承 ObserverWrapper,可以感知生命周期,会在页面活跃的时候更新观察者 AlwaysActiveObserver:继承 ObserverWrapper ,无法感知生命周期...发送数据 setValue protected void setValue(T value) { assertMainThread("setValue"); mVersion++; //...postTask) {//有待办直接 return return; } //将runnable 扔到主线程执行 ArchTaskExecutor.getInstance...super.postValue(value); } @Override public void setValue(T value) { super.setValue...(live1) { } mediator.addSource(live2){} mediator.observe(this){ } 通过 MediatorLiveData 将两个 MutableLiveData
1、LiveData 只能在主线程更新数据: 只能在主线程 setValue,即使 postValue 内部也是切换到主线程执行; 2、LiveData 数据重放问题: 注册新的订阅者,会重新收到 LiveData...() 优化); 4、LiveData 丢失数据问题: 在数据生产速度 > 数据消费速度时,LiveData 无法观察者能够接收到全部数据。...2.4 异步设置数据的执行过程 LiveData 使用 postValue() 方法进行异步设置数据(允许在子线程调用),内部会通过一个临时变量 mPendingData 存储数据,再通过 Handler...; 情况 3:观察者绑定的生命周期处于非活跃状态时,连续使用 setValue() / postValue() 设置数据时,观察将无法接收到中间的数据。...实现方法是在注册新观察者时,通过反射的手段将观察者持有的版本号(Observer#mLastVersion)同步为 LiveData 的版本号。缺点是使用反射,但确实能够解决多观察者问题。
当 LiveData 所持有的数据改变时,它会通知相应的界面代码进行更新。...被销毁时停止更新。...尤其是屏幕旋转的场景,常用的方法都是通过onSaveInstanceState()保存数据,再在onCreate()中恢复,真的是很麻烦。...getElapsedTime() { return mElapsedTime; } } LiveDataTimerViewModel很简单,在初始化时启动一个定时任务,每隔一秒通过...所以一旦需要互通的Fragment类名或包名不一致,就无法数据共享。
LiveData对象一旦连接到系统服务,任何需要该资源的Observer都只需观察这个LiveData对象。...//遍历LiveData的所有观察者执行下面代码 for (IteratorsetValue()其实最后就是通过调用了dispatchingValue()方法。...LiveData中的代码很简洁,400多行的代码,看起来也并不费劲,下面我们来分析下整个流程: 通过使用LiveData对象,为它创建观察者Observer 创建Observer时绑定Fragment生命周期...LifecycleBoundObserver生命周期变化时,dispatchValue下发更新LiveData中的值 当LiveData主动setValue时,会主动dispatchValue,并且会
使用 LiveData 保存数据时,由于数据和组件是分离的,所以当组件被销毁时可以保证数据不会丢失。...如 Activity执行finish方法后,它就不会收到任何LiveData 事件。 不再需要手动处理生命周期。...通过使用observe()方法将上述的LiveData对象和Observer对象关联在一起。...类将公开 setValue(T) 和 postValue(T) 方法。...setValue():注意到value=price这里是调用了setValue(price)方法,通过该方法更新LiveData的值,进而通知处于活跃状态的订阅者。
二、Observer到底可以接收多少次回调 2.1 为什么最多收到2个通知 这是一个典型的案例,在调试消息总线的场景时,我们通常会在消息的接收者那里打印一些log日志方便我们定位问题,然而日志的打印有时候也会给我们的问题定位带来一定的迷惑性...但是每次setValue的时候这个值都会加1。...2.2 配合ActivityViewModels要小心 Livedata的这种特性,在某些场景下会引发灾难性的后果,比如说,单Activity多Fragment的场景下,在没有Jetpack-mvvm组件之前...2.3 解决方案一:引入中间层 俗话说的好,计算机领域中的所有问题都可以通过引入一个中间层来解决。这里也一样,我们可以尝试“一个消息只被消费一次”的思路来解决上述的问题。...: 谨慎使用Android Studio给出的lambda智能提示 多关注是否真的需要Observe 在注册监听之前的消息 Activity与Fragment之间使用ActivityViewModel时要小心处理
发布: 发布者通过 getChannel() 获取消息通道,然后调用 setValue() 或者 postValue() 发布消息。...(MutableLiveData) bus.get(target); } public MutableLiveData getChannel(String target...) { return getChannel(target, Object.class); } } - 那么如何发送消息和接收消息呢,注意两者的key需要保持一致,否则无法接收?...tvText.setText(newText); } }); ### 07.遇到的问题和分析思路 - 遇到的问题: - 1.LiveData 一时使用一时爽...() 另一个是 postValue(),这两个方法的区别是,postValue() 在内部会抛到主线程去执行更新数据,因此适合在子线程中使用;而 setValue() 则是直接更新数据。
首先创建一个 MutableLiveData(LiveData是抽象类)对象 ,通过 observe 方法可以订阅修改数据的通知,通过 postValue()或者 setValue() 方法发送事件更新数据...LiveData并没有提供这样的功能,但是Architecture Component提供了MutableLiveData这样一个类,可以通过setValue(T)和postValue(T)方法来修改存储在...同样,通过这种方法修改LiveData中的值同样会触发所有对这个数据感兴趣的类。那么setValue()和postValue()有什么不同呢?...这个方法在分析下面setValue源码时还会说到,具体看下面的介绍!...发送源码分析 8.1 setValue源码分析 LiveData 更新数据方式有两个,一个是 setValue() 另一个是 postValue(),这两个方法的区别是,postValue() 在内部会抛到主线程去执行更新数据
一、LiveData 简介 ---- 在 视图 View 与 数据模型 Model 通过 ViewModel 架构组件 进行绑定后 , 可以立即 将 ViewModel 中的数据设置到 UI 界面中...中申请 HTTP 服务器数据 , 请求发送后 , 不知道什么时候才能获得响应 , 如果 过一段时间服务器才反馈响应数据 , 此时只能 通过 LiveData 将 ViewModel 的数据修改通知给...second.value = 0 } } 在该类中提供了 postValue 和 setValue 两个函数 , 在 UI 主线程 中调用 setValue 函数 , 在 非 UI 线程的子线程...void postValue(T value) @Override public void setValue(T value) } 然后 , 在 Activity 组件中 , 调用...Observer#onChanged 函数更新 UI 显示 ; 执行时切换屏幕方向 , 不影响数据累加显示 ; 四、ViewModel + LiveData + Fragment 通信示例 ----
内存泄漏检测工具显示MainActivity无法被回收。修改SettingsActivity的字符串资源时,MainActivity的UI显示异常。...而Resources对象与Context绑定,导致Activity无法销毁。在多语言切换时,静态Resources未更新,会引发UI错乱。在多个Activity之间传递Context的问题。...其他类需要时,通过构造函数或方法参数注入。...可测试性:依赖注入使得单元测试时可以轻松Mock全局对象。线程安全:通过参数传递而非静态共享,减少多线程冲突风险。...通过Arrays.toString(array)打印数组内容验证复制结果。在单元测试中模拟极端情况(如空数组、超大数组)。
不仅通过数据驱动完成彻底解耦,还兼顾了 Android 页面开发中其他不可预期的错误,例如Lifecycle 能在妥善处理 页面生命周期 避免view空指针问题,ViewModel使得UI发生重建时 无需重新向后台请求数据...,节省了开销,让视图重建时更快展示数据。...将 UserListViewModel 中的字段类型更改为 MutableLiveData。现在,更新数据时,系统会通知 UserListActivity。...3.2.2 获取数据 现在,我们已使用 LiveData 将 UserListViewModel 连接到UserListActivity,那么如何获取用户个人信息列表数据呢?...此方法就是调用Repository来执行,并且把数据设置到LiveData。
现在比较流行的方式是把他当做唯一数据源来驱动UI展示: view层:view (act / fragment) 数据逻辑层:viewModel 数据源:repository (db / network) 另外,还可以通过共享... text = new MutableLiveData(); } 在布局文件中使用, <layout xmlns:android="http://schemas.android.com...mCommonViewModel.hashCode())); } //点击按钮改变数据 public void changeData(View view) { mCommonViewModel.text.setValue...优缺点 优点: 页面退出时,自动销毁 屏幕旋转、语言切换后数据不丢失,而onSaveInstanceState在面对复杂数据时需要序列化 不持有view层,方便单元测试 缺点: 虽然要比onSaveInstanceState...简单,但是viewModel只能在屏幕旋转和语言切换后的页面重建维持数据,当页面意外销毁时数据无法恢复,而这点onSaveInstanceState可以做到,关于viewModel如何实现这一点,可以看我的下一篇笔记
避坑指南: 错误用法:在onCleared()中调用context引发内存泄漏 正确方案:通过AndroidViewModel+ApplicationContext注入 涨薪价值: 解决ViewModel...跨组件共享导致的数据污染问题(头条视频团队曾因此避免千万级事故) 面试答出作用域隔离方案,直接对标腾讯T3.2/阿里P6+职级 原理2:LiveData粘性事件机制(秒杀面试官陷阱题) ▍死亡连环问: "为什么先setValue...手写非粘性方案: class SingleLiveData : MutableLiveData() { privateval pending = AtomicBoolean(false...) overridefun setValue(value: T) { pending.set(true) super.setValue(value) }...} } } 涨薪价值: 今日头条因未处理粘性事件导致用户行为日志重复上报,损失日均300万数据 掌握此原理可冲击美团L8/快手K3A等高阶岗位 原理3:DataBinding编译时优化
notifyPropertyChanged方法来通知绑定get方法的控件重新执行get方法 package com.aruba.databinding2; import android.util.Log...this.name = new MutableLiveData(); this.name.setValue(name); this.star = new...MutableLiveData(); this.star.setValue(star); this.imageUrl = new MutableLiveData...(); this.imageUrl.setValue(imageUrl); this.score = new MutableLiveData(); this.score.setValue...void setImageUrl(String imageUrl) { this.imageUrl.setValue(imageUrl); } public MutableLiveData