LiveData源码赏析一 —— 基本使用

·  阅读 1964
LiveData源码赏析一 —— 基本使用

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第29天,点击查看活动详情

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被更新。

分类:
Android
标签:
收藏成功!
已添加到「」, 点击更改