Jetpack-LiveData

数据监听,会及时通知订阅者

LiveData

ViewModel+LiveData可以实现对数据的监听(在MVVM架构的层与层之间扮演着桥梁的作用。当数据发生变化时,通过LiveData让数据的订阅者得到通知。)

用viewmodel、liveData后的架构图

jetpack-用viewmodel、liveData后的架构图

用liveData的订阅者模式当页面数据变化时主动通知控件

LiveData是个可被观察的数据容器类。LiveData作为一个数据的容器可将数据包装起来,使数据成为被观察者,当数据变化时,观察者可获得通知。且我们不用自己去实现观察者模式,LiveData内部默认实现好了。

LiveData与ViewModel的关系

LiveData与ViewModel的关系

ViewModel存放页面所需的各种数据,还可以放一些与数据相关的业务逻辑。(如,可在ViewModel中对数据进行加工、获取等操作)

LiveData作用是在ViewModel中数据发生变化时通知页面。通常放在ViewModel中使用,用于包装ViewModel中那些需要被外界观察的数据。

LiveData的基本用法

还是计时器的功能

1
2
3
dependencies{
implementation "androidx.lifecycle:lifecycle-viewmodel:2.2.0"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class TimerWithLiveDataViewModel extends ViewModel{
private Timer timer;

//private int currentSecond;
//将 currentSecond这个字段用MutableLiveData包装起来
private MutableLiveData<Integer> currentSecond;
public LiveData<Integer> getCurrentSecond(){
if(currentSecond == null){
currentSecond = new MutableLiveData<>();
}
return currentSecond;
}

/**
* 开始计时
*/
public void startTiming(){
if (timer == null) {
currentSecond.setValue(0);
timer = new Timer();
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
currentSecond.setValue(currentSecond.getValue()+1);
}
};
timer.schedule(timerTask, 1000, 1000);
}
}

/**
* 清理资源
*/
@Override
public void onCleared(){
super.onCleared();
timer.cancel();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//使用这个 TimeViewModel
public class TimerActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
initComponent();
}

private void initComponent(){
final TextView tvTime = findViewById(R.id.tvTime);
//ViewModelProvider接收一个ViewModelStoreOwner对象作为参数。此处this指当前Activity
TimerWithLiveDataViewModel timerViewModel = new ViewModelProvider(this).get(TimerWithLiveDataViewModel.class);
//得到 ViewModel 中的 LiveData
final MutableLiveData<Integer> liveData = (MutableLiveData<Integer>) timerViewModel.getCurrentSecond();
//通过 LiveData.observe() 观察 ViewModel 中数据的变化
liveData.observe(this, new Observer<Integer>(){
@Override
public void onChanged(@Nullable Integer second){
//收到回调后更新 UI 界面
tvTime.setText("TIME:" + second);
}
});

//重置计时器
findViewById(R.id.btnResetTime).setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
//通过 LiveData.setValue() / LiveData.postValue() 完成对ViewModel中数据的更新
liveData.setValue(0);
}
})

timerViewModel.startTiming();
}
}

LiveData工作流程

LiveData 的 observe() 源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@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);
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;
}
owner.getLifecycle().addObserver(wrapper);
}

LiveData 通过 observe() 是有跟 LifecycleOwner 的生命周期绑定了(即跟Activity、Fragment等的生命周期绑定了)

LiveData setValue和postValue的区别

两者都是更新数据的作用

setValue()只能在主线程中调用;postValue()可在任何线程中调用。

LiveData.observeForever()方法

LiveData.observeForever()使用与 observe() 没有太大区别。主要区别在于,当LiveData所包装的数据发生变化时,无论页面处于什么状态,observeForever() 都能收到通知。因此,在用完之后一定要调用 removeObserver() 方法来停止对 LiveData的观察,否则 LiveData 会一直处于激活状态,Activity则永远不会被系统自动回收,就会造成内存泄露。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
assertMainThread("observeForever");
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing instanceof LiveData.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
wrapper.activeStateChanged(true);
}

ps:源码中observeForever没有跟LifecycleOwner绑定(即没有跟Activity等的生命周期绑定)