LiveData源码分析,使用注意事项

LiveData核心字段的作用

//  锁对象,在子线程发送消息的时候,有并发
private final Object mDataLock = new Object();  
   //初始的数据版本version,在每次设置的数据的时候,version都会增长,标识数据的变化
    static final int START_VERSION = -1;                 
    private static final Object NOT_SET = new Object();

    private SafeIterableMap, ObserverWrapper> mObservers =
            new SafeIterableMap<>();

    // how many observers are in active state
	//当前活跃的观察者,有哪些,主要使指,永远的订阅者,和感知生命周期的订阅者(start.reume状态)
    private int mActiveCount = 0;       
	//具体保存的数据	
    private volatile Object mData = NOT_SET;          
    // when setData is called, we set the pending data and actual data swap happens on the main
    // thread
	   //通过子线程设置数据,会调度到主线程,这里
    private volatile Object mPendingData = NOT_SET;     
  //当前数据的verstion	
    private int mVersion = START_VERSION;         

    private boolean mDispatchingValue;
	
	 //标识,当前正在分发的数据,是否还有效 ,因为在分发数据的收,可能会设置新的数据
    @SuppressWarnings("FieldCanBeLocal")
    private boolean mDispatchInvalidated;           
    private final Runnable mPostValueRunnable = new Runnable() {
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            //noinspection unchecked
            setValue((T) newValue);
        }
    };  

先分析带有生命周期的注册方法,走一遍注册流程

   public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
	 //如果监听的生命周期,已经被销毁,直接返回
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {  
            // ignore
            return;
        }
		
		//创建一个生命周期监听观察者
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);   
		 //插入map中,如果原来已经有了,就会返回原来的,没有原来的就插入新的,返回null
        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);//监听生命周期
    }

-》生命周期观察类
 class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
        @NonNull final LifecycleOwner mOwner;

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

        @Override
        boolean shouldBeActive() { //重写的父类的方法,检查,当前状态,是否处于活跃状态
		//当状态,处于start,resume状态的时候,就是活跃状态,可以感知注册,感知LiveData数据的变化
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }

        @Override
		//生命周期回调,注册之后,发送生命周期回调
        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {  //如果已经使销毁状态
                removeObserver(mObserver);//久去移除,移除对Livedata的监听,和移除,对生命周期的监听
                return;
            }
			//在初次,注册,或者使生命周期变化的时候,非destory,调用这个方法
            activeStateChanged(shouldBeActive());   
        }

        @Override
		  //判断是否依附于给定的生命周期,在根据生命周期对象,移除LiveData的观察者的时候使用
        boolean isAttachedTo(LifecycleOwner owner) { 
            return mOwner == owner;
        }

        @Override
        void detachObserver() {             
            mOwner.getLifecycle().removeObserver(this); //不在监听生命周期对象
        }
    }

—》 activeStateChanged(shouldBeActive()); //查看父类的方法
    private abstract class ObserverWrapper {
        final Observer mObserver;
        boolean mActive;      //记录当前是否是活跃状态
        int mLastVersion = START_VERSION;        

        ObserverWrapper(Observer observer) {
            mObserver = observer;
        }

        abstract boolean shouldBeActive();

        boolean isAttachedTo(LifecycleOwner owner) {
            return false;
        }

        void detachObserver() {
        }

        void activeStateChanged(boolean newActive) {
  //下面的核心代码,只在活跃状态变化的时候执行,比如true->false,false-true,对应到生命周期就是,
//(true->false,)start,resume----stop,(false-true) 第一次初始化,stop->start,resume   

            if (newActive == mActive) {  
                return;
            }
            // immediately set active state, so we'd never dispatch anything to inactive
            // owner
            mActive = newActive;   //记录最新activie
            boolean wasInactive = LiveData.this.mActiveCount == 0;   //判断当前是否是Inactive
			 //如果是变为活跃状态,就要活跃状态+1,如果是变为非活跃状态
            LiveData.this.mActiveCount += mActive ? 1 : -1; 
			//如果是无效状态,当前变为有效状态,就会执行 onActive(); 
            if (wasInactive && mActive) {
                onActive();
            }
			 //如果是,活跃的监听者第一次变为0,执行     onInactive();
            if (LiveData.this.mActiveCount == 0 && !mActive) { 
                onInactive();
            }
            if (mActive) {//变为活跃状态,比如第一次注册,并且是活跃状态,就会执行分发View
                dispatchingValue(this);  //去分发View
            }
        }
    }

-》 dispatchingValue(this);           //去分发value
   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, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

  -》 considerNotify(initiator);  //检查状态,调用观察者
    private void considerNotify(ObserverWrapper observer) {
        if (!observer.mActive) {//如果不在处于活跃状态,就返回
            return;
        }
        // Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
        //
        // we still first check observer.active to keep it as the entrance for events. So even if
        // the observer moved to an active state, if we've not received that event, we better not
        // notify for a more predictable notification order.
        if (!observer.shouldBeActive()) { //检查本监听者,依附的生命周期的状态,
		
	//如果不在活跃,调用改变为false,减少活跃数量,价差是否需要调用onInactive,但是不会移除观察者
            observer.activeStateChanged(false);
				//只有,生命周期变为destory
            return;
        }
        if (observer.mLastVersion >= mVersion) {   //如果观察者记录的数据版本,已经是最新,就返回
            return;
        }
        observer.mLastVersion = mVersion;                   //设置数据版本
        //noinspection unchecked
        observer.mObserver.onChanged((T) mData);     //调用数据变化
    }

上面分析了,从第一次注册,并且,刚好处于活跃状态,到执行回调的过程,下面分析一下,setValue,看分发数据的过程

  protected void setValue(T value) {
        assertMainThread("setValue");   //必须要在主线程执行
		 //每次设置数据,都会增加,只是做版本记录,用来观察者来检查是否是最新的数据
        mVersion++;  
        mData = value;//设置数据
        dispatchingValue(null);//分发数据,
    }
	
-》    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, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
			//和上面的发送数据逻辑一直,主要检查生命周期状态,然后发送数据
                    considerNotify(iterator.next().getValue()); 
                    if (mDispatchInvalidated) {//数据变化,就暂停
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);           //分发数据,为什莫要用循环?
		//为了防止在分发数据的时候,数据被修改了,如果修改了,就暂停分发,重新用新的数据分发
		//但是分发执行在主线程,为什莫会修改,不是因为线程,是因为监听方法中,重新修改了值,就会重新分发
		//主要为了处理这种情况,并且如果没有出口,一直修改,就会递归,导致线程堵塞,栈溢出等等情况
        mDispatchingValue = false;  //标识数据分发完了
    }

子线程发送数据

下面分析子线程发送数据,
	//mPendingData即将发送的数据,用来存储即将发送的数据和标识,状态,
    protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
		//如果mPendingData==NOT_SET;  代表没有待发送的数据,就要本次设置数据发送数据
		//如果mPendingData!=NOT_SET 代表现在有待发送的数据,并且消息已经调度到主线程,或者即将执行调度消息
		//所以不需要发送调度到主线程,只需要把mPendingData设置为最新的值,就可以
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);//调度到主线程去执行
		
    }
	
	//为什莫要添加锁,再多线程调用postValue的时候,如果不添加同步块,会导致,可能会多次发送调度消息,给你主线程,
	//比如说,如果判断了postTask = mPendingData == NOT_SET true,再执行下下面的赋值的之后,其他线程去执行,就导致
	//其他线程,也判断postTask=true,就会导致,发送多次调度消息,出现消息发送重复
	
//和下面的主线程执行的时候,也一样,   newValue = mPendingData;使用了最新的数据分发,之后再设置的就只能等到下一次分发,
//所以必须同时设置mPendingData = NOT_SET;执行完第一步,第二部还没执行,又有消息发送,就会判断错误,导致没有发送调度消息,
//可能会丢失消息
	
	    private final Runnable mPostValueRunnable = new Runnable() {
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {   
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            //noinspection unchecked
            setValue((T) newValue);
        }
    };

使用特性总结:
1.一个观察者,观察一个Livedate,不能同时注册两个生命周期的对象,会出错
2.onActive();  和 onInactive();  在生命周期变化的时候,可能会多次执行,
所以,如果对于直想执行一次的时候,比如封装的网络请求,就要添加boolean作为第一次执行的判断

3.对于onActive();  和 onInactive();  中封装的可以多次执行的,得以用来做,感知生命周期,
比如注册监听,onActive(); 注册,ononInactive注销

4.使用LiveData需要注意特性,会分发最新的Data,如果注册的观察者,不是处在活跃状态,就不会回调,
在变为活跃的时候,会接受最新的数据,所以可能会丢失数据

5.不保证监听者数据肯定会调用,对于和ui无关,和逻辑相关的操作,如果依附的生命周期,
走了销毁,那可能最新的数据就不会接受,会导致,可能核心的方法不会被调用

封装网络请求的经验总结
1.因为在页面被销毁的时候,就不在能收到数据,所以就没有回调了,所以,封装的网络请求,我们的逻辑代码,
不要依附于失败的回调,不依附于,失败完成的回调,就是如果因为页面销毁,导致,网络请求回调不完整,
不会影响逻辑

2.封装的时候要注意,原来的封装,一个网络请求,会发送多个消息,开始消息,成功执行消息,失败消息,
成功的完成消息,失败的完成消息,,一个网络请求要接受多个消息但是如果刚好,现在去打开去其他的页面,
会导致监听者,不在处于活跃状态,所以如果在非活跃期间,如果发送了三个消息,只会保留最后一个消息,在页面返回之后,
又处于活跃状态,可以收到最新的消息,但是已经丢失了中间的消息,会导致网络回调不完整,会出现一个bug

3.修复2的问题的方法是,无论当前接收者是否处于活跃状态,都要记录网络请求的结果,在监听变为活跃的时候
,把最新的消息发送过去,然后解析最新的消息,解析为回调


4.解决方法2还有一个方法就是,分开逻辑操作和更新ui操作,LiveData是感知生命周期的,在页面关闭的时候,
确实不在应该操作ui,所以没有回调感觉合理,但是在感知生命周期之后,还是需要处理一些结尾工作,
或者网络请求需要生命周期的完整性,来完成执行的逻辑,所以,通过一个特殊LivaDate,也可以有回调

你可能感兴趣的:(jetpack)