细说Jetpack中那些LiveData们

2021-12-17  本文已影响0人  要早点睡

1)低调的CoroutinLiveData

liveData { 
    this.emit("data") //1处
}.observe(owner){
    data -> doSomething(data)//2处
}

开局一段代码

public fun <T> liveData(
    context: CoroutineContext = EmptyCoroutineContext,
    timeout: Duration,
    @BuilderInference block: suspend LiveDataScope<T>.() -> Unit
): LiveData<T> = CoroutineLiveData(context, timeout.toMillis(), block)

CoroutineLiveData继承MediatorLiveData(下一章节介绍MediatorLiveData)

1.1)block代码块中的代码执行时机会执行多次吗?

内部实现代码有删减只保留关键部分。

internal class CoroutineLiveData<T>(
    context: CoroutineContext = EmptyCoroutineContext,
    timeoutInMs: Long = DEFAULT_TIMEOUT,
    block: Block<T>
) : MediatorLiveData<T>() {
    private var blockRunner: BlockRunner<T>?
    init {
        val supervisorJob = SupervisorJob(context[Job])
        val scope = CoroutineScope(Dispatchers.Main.immediate + context + supervisorJob)
        //注释3.对象创建时会构建一个BlockRunner对象
        blockRunner = BlockRunner(   liveData = this,block = block,timeoutInMs = timeoutInMs, scope = scope)     
         {
            blockRunner = null//注释4 最后一个参数是,此处会在代码块执行到末尾时执行。
        }
    }
    override fun onActive() {
        super.onActive()
        blockRunner?.maybeRun() //注释5 活跃时尝试执行代码块,如果blockRunner为空就不会执行
    }
}

internal class BlockRunner<T>(..) {
    private var runningJob: Job? = null
    @MainThread
    fun maybeRun() {
        if (runningJob != null)  return //注释7. 如果runningJob不为空也不会执行。
        runningJob = scope.launch {
           block(liveDataScope)//执行代码块
           onDone()
        }
    }
}

1.2)取消的超时机制怎么实现的?

# BlockRunner
fun cancel() { //LiveData onInactive()时被调用
    cancellationJob = scope.launch(Dispatchers.Main.immediate) {
        delay(timeoutInMs) //注释10处
        if (!liveData.hasActiveObservers()) {
            runningJob?.cancel()
            runningJob = null //注释11
        }
    }
}
 fun maybeRun() {
        cancellationJob?.cancel()//注释11
        cancellationJob = null
        runningJob?.cancel()
        ...
 }

  1. 多面手MediatorLiveData

image.png

2.1) 用MediatorLiveData监听其他LiveData的数据变化。

2.2) 内部实现

private static class Source<V> implements Observer<V> {
    final LiveData<V> mLiveData;
    final Observer<? super V> mObserver;
    int mVersion = START_VERSION;
    
    void plug() {  mLiveData.observeForever(this);  }
    void unplug() { mLiveData.removeObserver(this); }
    
    @Override
    public void onChanged(@Nullable V v) {
        if (mVersion != mLiveData.getVersion()) {//会对比版本
            mVersion = mLiveData.getVersion();
            mObserver.onChanged(v);
        }
    }
}

  1. 小透明SavingStateLiveData

这个类的位置在 lifecycle-viewmodel-savedstate的SavedStateHandle类中,也是继承自MutableLiveData,其与MutableLiveData最大的不同是多了两个属性。

private String mKey;
private SavedStateHandle mHandle;

作用是保证,LiveData所在的Viewmodel重建时,能够拿到销毁前的数据。

  1. 小结

本文介绍了Jetpack中,LiveData比较有特点的子类。

视频:
Android中高级进阶之MVVM与JetPack: LiveData
资深架构师逐题详解Android大厂精选高频面试题之LiveData
原文: https://juejin.cn/post/7034768099198894117#comment

上一篇下一篇

猜你喜欢

热点阅读