jetpack-LiveData

LiveData

LiveData优点

  • 确保界面符合数据状态

LiveData 遵循观察者模式。当生命周期状态发生变化时,LiveData 会通知 Observer 对象。您可以整合代码以在这些 Observer 对象中更新界面。观察者可以在每次发生更改时更新界面,而不是在每次应用数据发生更改时更新界面。

  • 不会发生内存泄漏

观察者会绑定到 Lifecycle 对象,并在其关联的生命周期遭到销毁后进行自我清理

  • 不会因 Activity 停止而导致崩溃

如果观察者的生命周期处于非活跃状态(如返回栈中的 Activity),则它不会接收任何 LiveData 事件。

  • 不再需要手动处理生命周期

界面组件只是观察相关数据,不会停止或恢复观察。LiveData 将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化。

  • 数据始终保持最新状态

如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。例如,曾经在后台的 Activity 会在返回前台后立即接收最新的数据。

  • 适当的配置更改

如果由于配置更改(如设备旋转)而重新创建了 Activity 或 Fragment,它会立即接收最新的可用数据。

  • 共享资源

您可以使用单一实例模式扩展 LiveData 对象以封装系统服务,以便在应用中共享它们。LiveData 对象连接到系统服务一次,然后需要相应资源的任何观察者只需观察 LiveData 对象

LiveData原理分析

LiveData本质上就是基于Lifecycle来实现的。观察LiveData从源码上来说就是通过传入的LifecycleOwner(Activity/Fragment)获取到LifecycleRegistry,通过它的addObserver方法向其中添加了一个LifecycleObserver的实现类。也就是说它是基于Lifecycle实现的

简单使用:

一般我们会在Activity或Fragment中调用LiveData的observe函数

mViewModel.dataList.observe(viewLifecycleOwner, Observer {
    ...
}

LiveData.observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)

@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    assertMainThread("observe");    //必须在主线程观察LiveData
    //如果LifecycleOwner的当前状态为DESTROYED,也就是已经被销毁了,就直接返回
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        // ignore
        return;
    }
    //将LifecycleOwner和Observer封装到LifecycleBoundObserver中
    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;
    }
    //getLifecycle方法获取LifecycleOwner持有的LifecycleRegistry,调用它的addObserver方法将LifecycleBoundObserver
    owner.getLifecycle().addObserver(wrapper);
}

从上面的代码可以看出,LiveData的observe方法本质上就是通过传入的LifecycleOwner获取到LifecycleRegistry,通过它的addObserver方法向其中添加了一个LifecycleObserver的实现类。也就是说它是基于Lifecycle实现的

LifecycleRegistry.addObserver()

@Override
public void addObserver(@NonNull LifecycleObserver observer) {
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

    if (previous != null) {
        return;
    }
    //获取LifecycleRegistry通过弱引用持有的LifecycleOwner对象,如果它为null,说明已经销毁并被GC
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    if (lifecycleOwner == null) {
        // it is null we should be destroyed. Fallback quickly
        return;
    }

    boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
    State targetState = calculateTargetState(observer);
    mAddingObserverCounter++;
    while ((statefulObserver.mState.compareTo(targetState) < 0
            && mObserverMap.contains(observer))) {
        pushParentState(statefulObserver.mState);
        statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
        popParentState();
        // mState / subling may have been changed recalculate
        targetState = calculateTargetState(observer);
    }

    if (!isReentrance) {
        // we do sync only on the top level.
        sync();
    }
    mAddingObserverCounter--;
}

Transformation.map()和Transformation.switchMap()

Transformation.map()

作用:通过对传入的LiveData应用转换函数,将其转换为其他类型的一个新的LiveData对象。新对象是基于并通过原对象转换生成的。

简单使用

LiveData<User> userLiveData = ...;
LiveData<String> userFullNameLiveData =
    Transformations.map(
        userLiveData,
        user -> user.firstName + user.lastName);
});

Transformation.switchMap()

作用:每当传入的LiveData发生变化时,就会将转换函数中返回的LiveData对象转换为一个新的LiveData对象。

使用场景

ViewModel中的某个LiveData对象是调用另外的方法来获取的,那么就可以将这个LiveData对象转换为另一个LiveData对象。

简单使用

class UserViewModel extends AndroidViewModel {
    MutableLiveData<String> nameQueryLiveData = ...

    LiveData<List<String>> getUsersWithNameLiveData() {
        return Transformations.switchMap(
            nameQueryLiveData,
                name -> myDataSource.getUsersWithNameLiveData(name));
    }

    void setNameQuery(String name) {
        this.nameQueryLiveData.setValue(name);
    }
}

参考资料

LiveData 概览

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值