1.LiveData是基于观察者模式,可以用于处理消息的订阅分发的组件。
LiveData组件有以下特性:
1) 可以感知Activity、Fragment生命周期变化,因为他把自己注册成LifecycleObserver。
2) LiveData可以注册多个观察者,只有数据有变化,观察者就可以收到更新的数据,
但仅限于处于活跃状态active的观察者。
3) 在onDestroy时,LiveData会自动回收注册的观察者,不会导致Activity内存泄漏。
2.简单使用介绍:
1)创建LiveData对象,并注册观察者。
- TextView ageTv = findViewById(R.id.age);
- TextView nameTv = findViewById(R.id.name);
- MutableLiveData<Person> liveData = new MutableLiveData();
- liveData.observe(this, new Observer<Person>() {
- @Override
- public void onChanged(Person person) {
- ageTv.setText(String.valueOf(person.age));
- nameTv.setText(person.name);
- }
- });
2)通过setValue改变数据:这时会调用上面的onChanged()方法,从而实现了数据驱动UI。后面会进行源码分析他的实现逻辑。
- findViewById(R.id.set_value).setOnClickListener(v -> {
- Person person = new Person();
- person.age = this.age++;
- person.name = "xiaohua";
- liveData.setValue(person);
- });
3)子线程中数据变化,得需要调用postValue,发送到主线程执行,因为在子线程是无法更新UI的。
- findViewById(R.id.post_value).setOnClickListener(v -> {
- new Thread(){
- @Override
- public void run() {
- super.run();
- Person person = new Person();
- person.age = MainActivity.this.age++;
- person.name = "xiaohua";
- liveData.postValue(person);
- }
- }.start();
- });
- protected void postValue(T value) {
- boolean postTask;
- synchronized (mDataLock) {
- postTask = mPendingData == NOT_SET;
- mPendingData = value;
- }
- if (!postTask) {
- return;
- }
- ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
- }
- private final Runnable mPostValueRunnable = new Runnable() {
- @SuppressWarnings("unchecked")
- @Override
- public void run() {
- Object newValue;
- synchronized (mDataLock) {
- newValue = mPendingData;
- mPendingData = NOT_SET;
- }
- setValue((T) newValue);
- }
- };
如果在子线程冲调用setValue会抛出下面的异常:
- java.lang.IllegalStateException: Cannot invoke setValue on a background thread
- at androidx.lifecycle.LiveData.assertMainThread(LiveData.java:487)
- at androidx.lifecycle.LiveData.setValue(LiveData.java:306)
- at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
- at com.example.jetpack.MainActivity$2.run(MainActivity.java:52)
4)只要数据源发生了变化,调用setValue或postValue,在LiveData注册的观察者
就会回调onChanged方法,在这个方法中,可以接收到数据的更新。