阅读 218

[问答记录]三方技术组件:谷歌 Jetpack LiveData

Q1:LiveData 使用方式,以及要解决的问题?

A1:LiveData 是有状态变化的数据,内部采用:“观察者”设计模式来实现,主题对象是:生命周期(LifecycleOwner),观察者由依赖LiveData数据的的工作场景提供。

初始化:

private LiveData<String> liveData = new MutableLiveData<String>("初始值"){
        // Called when the number of active observers change to 1 from 0.
        @Override
        protected void onActive() {
            super.onActive();
        }

        // Called when the number of active observers change from 1 to 0.
        @Override
        protected void onInactive() {
            super.onInactive();
        }
    };
复制代码

既然提到了观察者,如果主题有多个,LiveData 提供了 MediatorLiveData来管理多个 LiveData 数据源。

LiveData<Integer> liveData1 = ...;
LiveData<Integer> liveData2 = ...;

MediatorLiveData<Integer> liveDataMerger = new MediatorLiveData<>();
liveDataMerger.addSource(liveData1, value -> liveDataMerger.setValue(value));
liveDataMerger.addSource(liveData2, value -> liveDataMerger.setValue(value));

liveDataMerger.addSource(liveData1, new Observer<Integer>() {
       private int count = 1;
 
       {@literal @}Override public void onChanged(@Nullable Integer s) {
           count++;
           liveDataMerger.setValue(s);
           if (count > 10) {
               liveDataMerger.removeSource(liveData1);
           }
       }
  });
复制代码

观察者有两种模式:依赖生命周期和永久。

public void observe(@NonNull LifecycleOwner owner, 
@NonNull Observer<? super T> observer) {
}

public void observeForever(@NonNull Observer<? super T> observer) {
}
复制代码

LiveData 作用:

  • 是可以跟Android生命周期状态联动,DESTROYED 生命周期时,移除观察者。
  • 状态数据。提供了对象之间一对多的依赖,当 LiveData 内数据发生变化时,它的所有观察者都可以收到通知并作出更新。

应用场景

  • MVVM工程结构

Q2:LiveData 多线程场景下有哪些注意事项?

A2:因为和生命周期有关,所以:观察者的注册、数据更新 setValue 等都需要主线程,非主线程操作会有断言错误。

如果异步线程想要更新数据,可以使用 #postValue(也是抛到主线程来完成)。

Q3:LiveData 实现方式,有哪些可以应用在其他工作场景中的?

A3:大体有以下几点:

  • 在并发场景下,当需要安全遍历散列数据时,可以参考使用:SafeIterableMap

    • 非线程安全,只是在并发中可以安全遍历。
    • 支持多种Iterator遍历方式。
package androidx.arch.core.internal;
/**
 * LinkedList, which pretends to be a map and supports modifications during iterations.
 * It is NOT thread safe.
 *
 * @param <K> Key type
 * @param <V> Value type
 * @hide
 */
public class SafeIterableMap<K, V> implements Iterable<Map.Entry<K, V>> {
}
复制代码
  • 将任务抛到主线程的工具类。
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
复制代码
文章分类
Android