Jetpack - LiveData的入门和源码分析

265 阅读4分钟

什么是LiveData

LiveData是一个可以被观察的数据持有类,它可以感知并遵循Activity,Fragment等组件的生命周期。由于LiveData对组件生命周期可感知的特点,所以我们可以在组件的生命周期处于激活状态的时候更新UI数据。

LiveData主要功能-- 传递数据

现有通信框架总结

通信方法优点缺点
Handler系统原生,能实现线程间通信高耦合 不利于维护 容易导致内存泄漏
Broadcast简单性能差,传播数据有限 打乱代码的执行逻辑
interface速度快,容易理解实现复杂,不利于维护
rxbus效率高,无内存泄漏基于rxjava,学习成本高且依赖包太大
Eventbus使用简单混淆问题,无法感知组件生命周期 实现复杂

简单使用

class MainActivity : AppCompatActivity() {

    var binding: ActivityMainBinding ? = null

    var liveData:MutableLiveData<String>?=null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding=DataBindingUtil.setContentView(this,R.layout.activity_main)

        liveData = MutableLiveData();
        val bean = User("arrom", 18);
        binding?.user = bean
        liveData?.observe(this, {
           //更新UI
            bean.name = "observe${it}"
            bean.notifyChange()
            Log.d("MainActivity","observe${it}")
        })
        binding?.clickBtn?.setOnClickListener {
            Log.d("MainActivity","按钮点击事件")
            liveData?.value = " livedata xujie-->>>>"
        }
    }
}

如果在子线程中发送消息请使用postValue

liveData?.postValue(" livedata xujie-->>>>")

源码分析

先来看一下观察者订阅的方法observe(),第一参数是LifecycleOwner,第二个参数是观察者,也是最后接收回调的地方

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

新建一个对象LifecycleBoundObserver,最后将LifecycleBoundObserverLifecycleOwner进行了绑定

进入LifecycleBoundObserver类中

class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
    @NonNull
    final LifecycleOwner mOwner;

    LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
        super(observer);
        mOwner = owner;
    }

    @Override
    boolean shouldBeActive() {
        return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
    }
   
    @Override
    public void onStateChanged(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {
        if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
            removeObserver(mObserver);
            return;
        }
        //当生命周期发生变化时执行
        
        activeStateChanged(shouldBeActive());
    }

    @Override
    boolean isAttachedTo(LifecycleOwner owner) {
        return mOwner == owner;
    }

    @Override
    void detachObserver() {
        mOwner.getLifecycle().removeObserver(this);
    }
}

可以看到这里面与LifecycleOwner进行了绑定,并且实现了onStateChanged方法,当生命周期发生变化时执行activeStateChanged(shouldBeActive());方法。

shouldBeActive

STATE 为STARTED/RESUMED就是说生命周期的方法为onStart()onResume()onPause()时都表示active,这3个状态都可以接收数据更新

onStateChanged

是GenericLifecycleObserver接口的方法,当生命周期变化的时候会回调它。这里会做判断,如果是已经destroy,直接移除观察者;否则会调用 activeStateChanged 方法。

//这里是调用了lifecycle的方法,如果Lifecycle 的 STATE 为`STARTED/RESUMED`则返回true
@Override
boolean shouldBeActive() {
    return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}

void activeStateChanged(boolean newActive) {
    if (newActive == mActive) {
        return;
    }
    mActive = newActive;
    boolean wasInactive = LiveData.this.mActiveCount == 0;
    LiveData.this.mActiveCount += mActive ? 1 : -1;
    if (wasInactive && mActive) {
        onActive();
    }
    if (LiveData.this.mActiveCount == 0 && !mActive) {
        onInactive();
    }
    if (mActive) {
        dispatchingValue(this);
    }
}

LiveData类

/**
 * Called when the number of active observers change to 1 from 0.
 * <p>
 * This callback can be used to know that this LiveData is being used thus should be kept
 * up to date.
 */
protected void onActive() {

}

/**
 * Called when the number of active observers change from 1 to 0.
 * <p>
 * This does not mean that there are no observers left, there may still be observers but their
 * lifecycle states aren't {@link Lifecycle.State#STARTED} or {@link Lifecycle.State#RESUMED}
 * (like an Activity in the back stack).
 * <p>
 * You can check if there are observers via {@link #hasObservers()}.
 */
protected void onInactive() {

}

要求生命周期至少是STARTED状态才被认为是activie状态;

如果state是DESTROYED状态时,解绑LifecycleOwnerLiveData

进入dispatchingValue方法

void dispatchingValue(@Nullable ObserverWrapper initiator) {
    if (mDispatchingValue) {
        mDispatchInvalidated = true;
        return;
    }
    mDispatchingValue = true;
    do {
        mDispatchInvalidated = false;
        if (initiator != null) {
            considerNotify(initiator);
            initiator = null;
        } else {
           //遍历LiveData的所有观察者 
           
            for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                considerNotify(iterator.next().getValue());
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    mDispatchingValue = false;
}

进入considerNotify方法

private void considerNotify(ObserverWrapper observer) {
    if (!observer.mActive) {
        return;
    }
    if (!observer.shouldBeActive()) {
        observer.activeStateChanged(false);
        return;
    }
    if (observer.mLastVersion >= mVersion) {
        return;
    }
    observer.mLastVersion = mVersion;
    //调用更新数据的方法
    
    observer.mObserver.onChanged((T) mData);
}

LiveData的数据更新以及数据回调的整个过程大致如下。

setValue()其实最后就是通过调用了dispatchingValue()方法来实现的。

postValue方法
public void postValue(T value) {
    super.postValue(value);
}

LiveData类

protected void postValue(T value) {
    boolean postTask;
    synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;
        mPendingData = value;
    }
    if (!postTask) {
        return;
    }
   //切换到主线程 
   ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

其他和setValue一样

private final Runnable mPostValueRunnable = new Runnable() {
    @SuppressWarnings("unchecked")
    @Override
    public void run() {
        Object newValue;
        synchronized (mDataLock) {
            newValue = mPendingData;
            mPendingData = NOT_SET;
        }
        setValue((T) newValue);
    }
};
LiveData原理

image.png

LiveData源码总结

  • LiveData的观察者可以联动生命周期, 也可以不联动。在联动生命周期时,会自动在 DESTROYED 的状态下移除 Observer ,取消订阅,所以不用担心内存泄露;
  • LiveData的观察者只能与一个LifecycleOwner绑定, 否则会抛出异常。而一个 owner 可以绑定多个 Observer 实例;
  • LiveData 跟 LifecycleOwner 绑定,能感知生命周期变化,并且只会在 LifecycleOwner 处于 Active 状态(STARTED/RESUMED)下通知数据改变;如果数据改变发生在非 active 状态,数据会变化,但是不发送通知,等 owner 回到 active 的状态下,再发送通知;
  • 使用observeForever()方法,会注意AlwaysActiveObserver对象,意味着给定的观察者将接收所有事件,并且永远不会被自动删除,不管在什么状态下都能接收到数据的更改通知
  • LiveData 利用版本管理、绑定 Lifecycle 确保了只会发送最新的数据给 active 状态下的 Observer