微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

LiveData源码赏析 —— 基本使用

作者:晚来天欲雪_
转载地址:https://juejin.cn/post/7112991690914267143

LiveData是一个抽象类,我们一般使用mutablelivedata创建LiveData对象。

public class mutablelivedata<T> extends LiveData<T> {}

mutablelivedata仅仅继承了LiveData,没有做其他额外的操作。

@MainThread
public void observe(@NonNull LifecycleOwner owner,@NonNull Observer<? super T> observer) {
    assertMainThread("observe");
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        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);
}

1.首先assertMainThread()方法会先判断当前调用线程,如果不在主线程则会抛出异常
2.然后通过owner获取Lifecycle当前所处于的状态,如果已经销毁(DESTROYED),则此时注册观察者毫无意义,直接忽略。
3.将owner和observer包装成LifecycleBoundobserver对象。
4.将observer作为key,wrapper作为value存储在mObservers,如果mObservers之前不存在observer,putIfAbsent()方法直接添加并返回null,如果已经存在,则依旧为原来的值,并返回旧的值。
5.如果LiveData内部之前已经持有了observer对象并且绑定了其他LifecycleOwner对象,则抛出异常。
6.如果已经持有observer对象但是绑定的是同一个LifecycleOwner对象则忽略此次注册
7.将wrapper添加到Lifecycle。

observe()方法中将owner和observer包装成LifecycleBoundobserver对象,LifecycleBoundobserver不仅继承了ObserverWrapper抽象类,还实现了
LifecycleEventObserver接口,而LifecycleEventObserver实际继承于LifecycleObserver接口。

class LifecycleBoundobserver extends ObserverWrapper implements LifecycleEventObserver {
	//......省略部分代码
    boolean shouldBeActive() {
        return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
    }
    public void onStateChanged(@NonNull LifecycleOwner source,@NonNull Lifecycle.Event event) {
        Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
        if (currentState == DESTROYED) {
            removeObserver(mObserver);
            return;
        }
        Lifecycle.State prevstate = null;
        while (prevstate != currentState) {
            prevstate = currentState;
            activeStateChanged(shouldBeActive());
            currentState = mOwner.getLifecycle().getCurrentState();
        }
    }
    boolean isAttachedTo(LifecycleOwner owner) {
        return mOwner == owner;
    }
    void detachObserver() {
        mOwner.getLifecycle().removeObserver(this);
    }
}

LifecycleBoundobserver需要LifecycleOwner处于活跃状态,生命周期至少是STARTED状态,而且它是与生命周期绑定的,所以detachObserver()方法中需要将自己移除,当生命周期变化的时候会回调onStateChanged()方法,如果Lifecycle已经处于DESTROYED状态了,则主动移除mObserver,否则根据当前状态分发数据。

observeForever

observeForever()方法可以注册一个没有关联LifecycleOwner对象的Observer。在这种情况下Observer被认为始终处于活动状态,因此当有数据变化时总是会被通知。LiveData不会主动移除这些Observer,需要我们在合适的机会主动调用removeObserver()方法进行移除。

@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);
}
  1. observeForever()方法和observe()方法一样都必须在主线程调用
  2. 将observer包装成AlwaysActiveObserver对象。
  3. 如果LiveData内部之前已经持有了observer对象并且关联在LifecycleBoundobserver上面,则会抛出异常。
  4. 调用activeStateChanged()方法,因为当前 LiveData 可能已经被设置值了。
AlwaysActiveObserver也是ObserverWrapper的子类。
 private class AlwaysActiveObserver extends ObserverWrapper {
    AlwaysActiveObserver(Observer<? super T> observer) {
        super(observer);
    }
    boolean shouldBeActive() {
        return true;
    }
}

与LifecycleBoundobserver不同的是shouldBeActive()方法固定返回true,表明它一直是活跃状态。只要有数据变化都会进行回调,所以为了避免内存泄漏和空指针异常,我们应该在不需要Observer的时候将它移除。

removeObserver

@MainThread
public void removeObserver(@NonNull final Observer<? super T> observer) {
    assertMainThread("removeObserver");
    ObserverWrapper removed = mObservers.remove(observer);
    if (removed == null) {
        return;
    }
    removed.detachObserver();
    removed.activeStateChanged(false);
}
  1. 从map中移除Observer。
  2. 调用被移除的Observer的detachObserver方法并且把状态mActive置为false。

ObserverWrapper

前面提到的LifecycleBoundobserver和AlwaysActiveObserver都是ObserverWrapper的子类。

private abstract class ObserverWrapper {
    final Observer<? super T> mObserver;
    boolean mActive;
    int mLastVersion = START_VERSION;
	//省略部分代码.....
    void activeStateChanged(boolean newActive) {
        if (newActive == mActive) {
            return;
        }
        mActive = newActive;
        changeActiveCounter(mActive ? 1 : -1);
        if (mActive) {
            dispatchingValue(this);
        }
    }
}

ObserverWrapper对Observer做了一层包装,加入了活跃状态和版本信息,当活跃状态改变的时候会调用activeStateChanged()方法,他会统计Observer活跃数并且在Observer活跃的时候分发数据。

changeActiveCounter

@MainThread
void changeActiveCounter(int change) {
    int prevIoUsActiveCount = mActiveCount;
    mActiveCount += change;
    if (mChangingActiveState) {
        return;
    }
    mChangingActiveState = true;
    try {
        while (prevIoUsActiveCount != mActiveCount) {
            boolean needToCallActive = prevIoUsActiveCount == 0 && mActiveCount > 0;
            boolean needToCallInactive = prevIoUsActiveCount > 0 && mActiveCount == 0;
            prevIoUsActiveCount = mActiveCount;
            if (needToCallActive) {
                onActive();
            } else if (needToCallInactive) {
                onInactive();
            }
        }
    } finally {
        mChangingActiveState = false;
    }
}

changeActiveCounter()方法改变当前激活状态的observe数量,然后判断如果激活状态得数量由从0到1调用了onActive方法,激活状态数量由1到0调用了onInactive方法。这两个方法都是空实现,需要LiveData的子类按需要实现。加while是为了防止在执行过程中changeActiveCounter()方法调用,导致mActiveCount被更新。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐