Android Jetpack架构组件之LiveData

有时候,靠单纯的判断并不能确定成功的几率。与其在等待中浪费青春,不如在追求中燃烧生命。——《狼道》

目录

前言

一、简介

​二、基本使用

三、源码分析

四、内容推荐

五、项目参考


前言

——这篇记录的是一个常用的Jetpack架构组件之一的LiveData。通俗讲它有两个显著作用:1.通过观察者模式当数据发生变化的时候通知UI更新。2.与生命周期绑定在一起,当组件生命周期发生变化处于激活时通知UI更新。这么说可能还有点不清晰,具体请看下文分解:

一、简介

官网文档 / Jetpack组件

(1)是什么

——LiveData是一个可观察的数据持有者类。与常规的可观察对象不同,LiveData是生命周期感知的,这意味着它尊重其他应用程序组件(如活动、片段或服务)的生命周期。这种意识确保LiveData只更新处于活动生命周期状态的应用程序组件观察者。

(2)有什么用

  1. 数据可以被观察者订阅
  2. 能够感知组件(Fragment、Activity、Service)的生命周期
  3. 只有在组件出于激活状态(STARTED、RESUMED)才会通知观察者有数据更新

(3)有什么优点

  1. 能够保证数据和UI统一
  2. 减少内存泄漏
  3. 当Activity停止时不会引起崩溃
  4. 不需要额外的手动处理来响应生命周期的变化
  5. 组件和数据相关的内容能实时更新
  6. 针对configuration change时,不需要额外的处理来保存数据
  7. 资源共享

​二、基本使用

(4)怎么使用

LiveData的使用方式有两种:1.使用LiveData对象;2.继承LiveData类

  • 使用LiveData对象

实现步骤:

1.创建一个LiveData实例来保存数据

2.创建Observer监听数据改变

3.设置值,如果有活动的观察者,值将被发送给他们

//创建一个定义onChanged()方法的观察者对象,该方法控制LiveData对象持有的数据更改时发生的情况。
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 1.创建一个LiveData实例来保存数据
        MutableLiveData<String> currentName = new MutableLiveData<String>();
        // 2.创建Observer监听数据改变
        final Observer<String> nameObserver = new Observer<String>() {
            @Override
            public void onChanged(@Nullable final String newName) {
                //更新UI操作
                nameTextView.setText(newName);
            }
        };
        // 添加Observer
        currentName.observe(this, nameObserver);
       
    }

    public void onClick(View view){
        // 3.设置值 如果有活动的观察者 值将被发送给他们
        //主线程使用setValue
        model.getCurrentName().setValue("xxxx")
        //后台线程使用postValue
        //model.getCurrentName().postValue("xxxx")
    }
}
  • 继承LiveData类
//Demo1扩展LiveData类(监听网络状态)
public class NetworkLiveData extends LiveData<NetworkInfo> {

    private final Context mContext;
    static NetworkLiveData mNetworkLiveData;
    private NetworkReceiver mNetworkReceiver;
    private final IntentFilter mIntentFilter;

    private static final String TAG = "NetworkLiveData";

    public NetworkLiveData(Context context) {
        mContext = context.getApplicationContext();
        mNetworkReceiver = new NetworkReceiver();
        mIntentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
    }
    //单例
    public static NetworkLiveData getInstance(Context context) {
        if (mNetworkLiveData == null) {
            mNetworkLiveData = new NetworkLiveData(context);
        }
        return mNetworkLiveData;
    }

    @Override
    protected void onActive() {
        super.onActive();
        //当组件处于激活状态时注册广播
        mContext.registerReceiver(mNetworkReceiver, mIntentFilter);
    }

    @Override
    protected void onInactive() {
        super.onInactive();
         //当组件处于销毁状态时注销广播
        mContext.unregisterReceiver(mNetworkReceiver);
    }
    //监听网络状态
    private static class NetworkReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            ConnectivityManager manager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo activeNetwork = manager.getActiveNetworkInfo();
            getInstance(context).setValue(activeNetwork);
        }
    }
}

//使用过程
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        NetworkLiveData.getInstance(this).observe(this,new Observer(){
            @Override
            public void onChanged(@Nullable final String newName) {
                // Update UI
            }
        })
    }
}

LiveData的使用方式相对比较简单。实现方式也比较容易。就不描述太多细节。相信大家看代码会比看解释更容易理解。

三、源码分析

——因为LiveData是抽象类,所以我们要使用它就需要写一个类来继承LiveData。
——当然系统也帮我们写了几个可直接使用的类,MutableLiveData,MediatorLiveData。

1.MutableLiveData源码

// 创建了一个MutableLiveData实例
MutableLiveData<String> liveData = new MutableLiveData<>();
// MutableLiveData源码
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);
      }
}

——MutableLiveData把LiveData的postValue方法与setValue接口暴露出来可供调用。这个后面使用的时候在分析

2.LiveData的observe源码

//创建Observer监听数据改变
liveData.observe(this, new Observer<String>() {
	@Override
	public void onChanged(String s) {
		binding.setName(s);
	}
});

(1)observe源码

        //该方法主要把observer与Activity(组件)的生命周期绑定在一起。当Activity(组件)状态改变的时候通知observer
	@MainThread
	public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
		//请看(5) 
		assertMainThread("observe");
		//当前Activity(组件)状态处于销毁状态时 是则返回 
		if (owner.getLifecycle().getCurrentState() == DESTROYED) {
			// ignore
			return;
		}
		//请看(2) 
		LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
		//以键值对的形式存储observer于LifecycleBoundObserver,如果LifecycleBoundObserver已经存储过则ObserverWrapper返回空 
		ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
		//判断是否是同一个LifecycleOwner 
		if (existing != null && !existing.isAttachedTo(owner)) {
			throw new IllegalArgumentException("Cannot add the same observer"
					+ " with different lifecycles");
		}
		//这里拦截已经添加过的LifecycleBoundObserver
		if (existing != null) {
			return;
		}
		//添加一个wrapper,它将在LifecycleOwner状态更改时得到通知 具体原理可以看楼主Lifecycle原理篇
		owner.getLifecycle().addObserver(wrapper);
	}

(2)LiveData的内部类LifecycleBoundObserver源码

        //该类通过实现GenericLifecycleObserver监听生命周期变化更新Observer传递的数据
	//继承ObserverWrapper根据Activity(组件)的生命周期管理着Observer
	class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
		@NonNull
		final LifecycleOwner mOwner;
		//observer传给ObserverWrapper的构造函数
		LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
			super(observer);
			mOwner = owner;
		}
		//返回当前Activity(组件)的生命状态是否是STARTED或者RESUMED
		@Override
		boolean shouldBeActive() {
			return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
		}
		//通过实现GenericLifecycleObserver接口的onStateChanged方法监听Activity(组件)生命周期变化
		@Override
		public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
			//判断Activity(组件)生命周期状态是否是DESTROYED  是则移除观察者
			if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
				//请看(4)
				removeObserver(mObserver);
				return;
			}
			//Activity(组件)生命周期改变 通知ObserverWrapper
			activeStateChanged(shouldBeActive());
		}
		//重写ObserverWrapper的isAttachedTo方法判断是不是同一个生命周期
		@Override
		boolean isAttachedTo(LifecycleOwner owner) {
			return mOwner == owner;
		}
		//重写ObserverWrapper的detachObserver方法移除LifecycleBoundObserver
		@Override
		void detachObserver() {
			mOwner.getLifecycle().removeObserver(this);
		}
	}

(3)LiveData的内部抽象类ObserverWrapper源码

        // 封装Observer的一些属性与方法
	private abstract class ObserverWrapper {
		final Observer<? super T> mObserver;
		boolean mActive;
		int mLastVersion = START_VERSION;
		ObserverWrapper(Observer<? super T> observer) {
			mObserver = observer;
		}
		abstract boolean shouldBeActive();
		//判断是否是同一个生命周期
		boolean isAttachedTo(LifecycleOwner owner) {
			return false;
		}
		void detachObserver() {}		
		// 设置ObserverWrapper的mActive状态与添加mActiveCount数量 
		void activeStateChanged(boolean newActive) {
			//判断Activity(组件)状态是否改变 有没则返回
			if (newActive == mActive) {
				return;
			}
			//设置mActive状态
			mActive = newActive;
			//判断当前观察者数量是否为0
			boolean wasInactive = LiveData.this.mActiveCount == 0;
			//当Activity(组件)是激活状态时+1 反之-1
			LiveData.this.mActiveCount += mActive ? 1 : -1;
			//当Activity(组件)状态属于激活并wasInactive为ture时调用onActive() 
			if (wasInactive && mActive) {
				//也就是当观察者的数量从0变为1时调用
				onActive();
			}
			//当活动观察者的数量从1变为0时调用
			if (LiveData.this.mActiveCount == 0 && !mActive) {
				onInactive();
			}
			// 当Activity(组件)属于激活是调用dispatchingValue
			if (mActive) {
				//查看(6)分析
				dispatchingValue(this);
			}
		}
	}

(4)LiveData类的removeObserver方法

        //从观察者列表中删除给定的观察者
	@MainThread
	public void removeObserver(@NonNull final Observer<? super T> observer) {
		//请看(5) 
		assertMainThread("removeObserver");
		//从mObservers列表中移除observer
		ObserverWrapper removed = mObservers.remove(observer);
		if (removed == null) {
			return;
		}
		//移除Observer并通知相关属性记录更改
		removed.detachObserver();
		removed.activeStateChanged(false);
	}

(5)LiveData类的assertMainThread方法

        //用于判断是否在主线程  不是则抛出异常IllegalStateException
	private static void assertMainThread(String methodName) {
		if (!ArchTaskExecutor.getInstance().isMainThread()) {
			throw new IllegalStateException("Cannot invoke " + methodName + " on a background"
					+ " thread");
		}
	}

(6)LiveData类的dispatchingValue方法分析

        // 经过一系列的判断 最后调用considerNotify方法更新数据
	@SuppressWarnings("WeakerAccess") /* synthetic access */
	void dispatchingValue(@Nullable ObserverWrapper initiator) {
	    //判断值是否在分发当中 	
            if (mDispatchingValue) {
			mDispatchInvalidated = true;
			return;
		}
		mDispatchingValue = true;
		do {
			mDispatchInvalidated = false;
			if (initiator != null) {
				//请看(7) 
				considerNotify(initiator);
				initiator = null;
			} else {
				for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
						mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
					//请看(7) 
					considerNotify(iterator.next().getValue());
					if (mDispatchInvalidated) {
						break;
					}
				}
			}
		} while (mDispatchInvalidated);
			mDispatchingValue = false;
		}
        }

(7)LiveData类的considerNotify方法分析

        //当Activity(组件)属于激活状态时 把数据传给observer的onChanged方法
	private void considerNotify(ObserverWrapper observer) {
		// Activity(组件)状态属于非激活状态时 返回
		if (!observer.mActive) {
			return;
		}
		// 继续检测observer属于非激活状态时设置activeStateChanged为false 并返回
		if (!observer.shouldBeActive()) {
			observer.activeStateChanged(false);
			return;
		}
		// 用于拦截数据没更新,当调用setValue时mVersion会加1,也就是没有新数据时在这里会被拦截 不会调用到mObserver.onChanged方法
		if (observer.mLastVersion > = mVersion) {
			return;
		}
		observer.mLastVersion = mVersion;
		//把数据传给observer的onChanged方法
		observer.mObserver.onChanged((T) mData);
	}

总结:

  • 通过liveData.observe()方法首先判断组件若处于激活状态,创建绑定生命周期与观察者的关键类。
  • 判断该类是否存储过,若存储过则抛出异常。
  • 将绑定类添加到lifecycle生命周期中,监听组件生命周期变化。(具体实现方式看Lifecycle原理)
  • 当生命周期发生变化时调用观察者的onChange()方法 ,把值传递过去。中间经过一系列判断,具体看源码。

3.设置值setValue源码

        //通过解析1的MutableLiveData源码可知最后调用的是LiveData的setValue与postValue
	//设置值。如果有活动的观察者,值将被发送给他们
	@MainThread
	protected void setValue(T value) {
		assertMainThread("setValue");
		mVersion++;
		mData = value;
		//请看(6)
		dispatchingValue(null);
	}
	//非主线程设置值
	protected void postValue(T value) {
		boolean postTask;
		//同步代码块 
		synchronized (mDataLock) {
			postTask = mPendingData == NOT_SET;
			mPendingData = value;
		}
		//检测上一个任务是否执行完毕
		if (!postTask) {
			return;
		}
		//将任务发送到主线程以设置给定的值
		ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
	}	

    private final Runnable mPostValueRunnable = new Runnable() {
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            //最后也是通过setValue方法进行通知
            setValue((T) newValue);
        }
    };

总结:

  • postValue方法主要是将任务切换到主线程并调用了setValue方通知观察者。
  • 而setValue方法则是调用了dispatchingValue()将值分发给Observer.onChanged方法。

四、内容推荐

五、项目参考

本文相关代码及Demo都放在下面项目中。有兴趣可体验一把

Github / apk下载体验地址 / 扫码下载体验 

若您发现文章中存在错误或不足的地方,希望您能指出!

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值