美文网首页
LiveData源码分析

LiveData源码分析

作者: 24k金 | 来源:发表于2019-03-13 19:40 被阅读0次

一、LiveData简介
LiveData是google官方架构JetPack系列的一个响应式开发框架,LiveData是一个可以被观察的数据持有者类。说到响应式开发或者说观察者就不免想到RxJava,RxJava将观察者模式运用的炉火纯青。但LiveData和RxJava的定位是不一样的,LiveData主要用于搭建MVVM架构,并在其中作为数据持有者,LiveData能监听组件的生命周期变化,这样一来只会更新处于活跃状态的组件。
LiveData的特点:1)采用观察者模式自动提示UI更新。2)不需要手动处理生命周期,不会因为Activity的销毁重建而丢失数据。3)不会出现内存泄漏。4)不需要手动取消订阅,Activity在非活跃状态下(销毁、finish之后)不会收到数据更新信息。

二、LiveData用法
1)LiveData往往结合于ViewModel使用,对于ViewModel的分析之前已经进行分析了,这里不再过多描述。首先在ViewModel中创建LiveData,代码如下:

class MainViewModel : ViewModel() {

private val repertory: MainRepositoryby lazy { MainRepository()}

    var data: MutableLiveData = MutableLiveData()

fun getDataFromServer(){

repertory.getDataFromServer(data)

}
}

这里采用的是MutableLiveData,它是LiveData的实现类,LiveData是一个抽象类。
2)在Activity中观察LiveData的数据变化。代码如下:

class MainActivity : AppCompatActivity() {
 private lateinit var mModel: MainViewModel
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initData()
    }
    private fun initData() {
        mModel = ViewModelProviders.of(this)[MainViewModel::class.java]
        mModel.data?.observe(this, Observer {
            val mainAdapter = MainAdapter(this, it)
            val linearLayoutManager = LinearLayoutManager(this)
            rv.layoutManager = linearLayoutManager
            rv.adapter = mainAdapter
        })
        mModel.getDataFromServer()
    }
}

3)对LiveData进行赋值,代码如下:

fun postData() {
        mModel.data.postValue(JsonBean(ArrayList(), 0, ""))
    }

三、源码分析
1)首先先从实例化MutableLiveData入手,MutableLiveData是LiveData的实现类,源码如下:

public class MutableLiveData<T> extends LiveData<T> {
    @Override
    public void postValue(T value) {
        super.postValue(value);
    }
    @Override
    public void setValue(T value) {
        super.setValue(value);
    }
}

从代码中可以看到,LiveData是一个泛型类,泛型参数就是存储数据的实际类型,同时MutableLiveData提供两个赋值方法:postValue和setValue,而这两个方法直接调用父类中的方法。所以看一下父类中这两个方法的具体实现

  @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }

setValue方法必须在主线程调用,调用只有LiveData就持有新的数据了。

protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }

postValue方法同样是更新LiveData持有的数据,但区别在于postValue方法是单独采用Runnable通过主线程handler发送给主线程更新数据,这样一来postValue就可以在异线程更新数据了。其实postValue最终更新数据还是走的setValue方法。
2)分析在Activity中订阅LiveData的方法observe,此方法接收两个参数,一个LifecycleOwner和Observer<T>,代码如下:

@MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
        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);
    }

从中我们可以发现方法首先会判断当前视图状态是否已经是”DESTROYED“状态,在分析订阅方法之前先分析一下LifecycleOwner这个接口。

public interface LifecycleOwner {
    /**
     * Returns the Lifecycle of the provider.
     *
     * @return The lifecycle of the provider.
     */
    @NonNull
    Lifecycle getLifecycle();
}

在这个接口中只有一个方法用于返回Lifecycle。查看一下接口的实现类可以发现v4和v7包下的Acvitity和Fragment都实现了这个接口。接下来看一下Lifecycle这个抽象类。

public abstract class Lifecycle {
    @MainThread
    public abstract void addObserver(@NonNull LifecycleObserver observer);
    @MainThread
    public abstract void removeObserver(@NonNull LifecycleObserver observer);
    @MainThread
    @NonNull
    public abstract State getCurrentState();
.....省略部分代码
}

类中定义了添加和移除订阅者的方法,同时还包括订阅者的生命周期状态信息。而Lifecycle的唯一实现类是LifecycleRegistry,代码如下。

public class LifecycleRegistry extends Lifecycle {
    private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new FastSafeIterableMap<>();
  
    private final WeakReference<LifecycleOwner> mLifecycleOwner;
    private int mAddingObserverCounter = 0;

    private boolean mHandlingEvent = false;
    private boolean mNewEventOccurred = false;
    private ArrayList<State> mParentStates = new ArrayList<>();
    public LifecycleRegistry(@NonNull LifecycleOwner provider) {
        mLifecycleOwner = new WeakReference<>(provider);
        mState = INITIALIZED;
    }
......省略部分代码

    private boolean isSynced() {
        if (mObserverMap.size() == 0) {
            return true;
        }
        State eldestObserverState = mObserverMap.eldest().getValue().mState;
        State newestObserverState = mObserverMap.newest().getValue().mState;
        return eldestObserverState == newestObserverState && mState == newestObserverState;
    }

    private State calculateTargetState(LifecycleObserver observer) {
        Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);

        State siblingState = previous != null ? previous.getValue().mState : null;
        State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1)
                : null;
        return min(min(mState, siblingState), parentState);
    }

    @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;
        }
        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--;
    }

    private void popParentState() {
        mParentStates.remove(mParentStates.size() - 1);
    }

    private void pushParentState(State state) {
        mParentStates.add(state);
    }

    @Override
    public void removeObserver(@NonNull LifecycleObserver observer) {
        mObserverMap.remove(observer);
    }
    @NonNull
    @Override
    public State getCurrentState() {
        return mState;
    }

    static State getStateAfter(Event event) {
        switch (event) {
            case ON_CREATE:
            case ON_STOP:
                return CREATED;
            case ON_START:
            case ON_PAUSE:
                return STARTED;
            case ON_RESUME:
                return RESUMED;
            case ON_DESTROY:
                return DESTROYED;
            case ON_ANY:
                break;
        }
        throw new IllegalArgumentException("Unexpected event value " + event);
    }

    private static Event downEvent(State state) {
        switch (state) {
            case INITIALIZED:
                throw new IllegalArgumentException();
            case CREATED:
                return ON_DESTROY;
            case STARTED:
                return ON_STOP;
            case RESUMED:
                return ON_PAUSE;
            case DESTROYED:
                throw new IllegalArgumentException();
        }
        throw new IllegalArgumentException("Unexpected state value " + state);
    }

    private static Event upEvent(State state) {
        switch (state) {
            case INITIALIZED:
            case DESTROYED:
                return ON_CREATE;
            case CREATED:
                return ON_START;
            case STARTED:
                return ON_RESUME;
            case RESUMED:
                throw new IllegalArgumentException();
        }
        throw new IllegalArgumentException("Unexpected state value " + state);
    }
.....省略部分代码
}

先来看一下主要的成员变量mObserverMap和mLifecycleOwner,mObserverMap是一个Map结构,以观察者为key存储观察者状态。mLifecycleOwner是一个弱引用,持有LifecycleOwner,其实LifecyleOwner就是Activity或者Fragment。前面说到过Activity中会实现LifecycleOwner接口,其实追踪到源码发现SupportActivity实现了LifecycleOwner接口,同时声明变量LifecycleRegistry,代码如下:

 private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

由此一来LifecycleRegistry就持有Activity的弱引用了,这样一来既能监听Activity的生命周期同时也不会造成内存泄漏。接下来看关键的订阅和取消订阅方法,取消订阅很简单就是将观察者移除Map集合,订阅方法会先校验观察者的生命周期状态,同时从软引用中获取LifecycleOwner,如果为空的话则说明界面已经被销毁了,则不需要进行订阅了。否则进行订阅操作。
现在回到前面继续分析LiveData的订阅操作,订阅操作会将owner和observer统一包装成LifecycleBoundObserver,这是Lifecycle真正的订阅者。

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

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

        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }

        @Override
        public void onStateChanged(LifecycleOwner source, 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);
        }
    }

类中封装了对于Lifecycle的状态赋值操作和状态改变对观察者进行取消订阅操作。最后将LifecycleBoundObserver传入LifecycleRegistry完成订阅。整体的订阅流程就分析完了。
3)Observer响应获取数据变化流程分析。
分析完订阅流程接下来分析LiveData如何响应数据变化通知给订阅者,这里需要从setValue方法入手。

   protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }

 private void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                considerNotify(initiator);
                initiator = null;
            } else {
                for (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

调用setValue方法后会调用dispatchingValue方法循环通知订阅者响应数据变化。

三、LiveData特点原理总结
1)采用观察者模式自动提示UI更新:
由于采用订阅方式获取数据变化所以自动获取数据更新。
2)不需要手动处理生命周期,不会因为Activity的销毁重建而丢失数据:
会自动重新订阅。
3)不会出现内存泄漏:
Lifecycle持有的是Activity(Fragment)的弱引用。
4)不需要手动取消订阅,Activity在非活跃状态下(销毁、finish之后)不会收到数据更新信息:
LifecycleRegistry会回调Activity的状态,在onDestory之后LiveData自动取消订阅。

相关文章

网友评论

      本文标题:LiveData源码分析

      本文链接:https://www.haomeiwen.com/subject/cotxmqtx.html