有时候,靠单纯的判断并不能确定成功的几率。与其在等待中浪费青春,不如在追求中燃烧生命。——《狼道》
目录
前言
一、简介
二、基本使用
三、源码分析
四、内容推荐
五、项目参考
前言
——这篇记录的是一个常用的Jetpack架构组件之一的LiveData。通俗讲它有两个显著作用:1.通过观察者模式当数据发生变化的时候通知UI更新。2.与生命周期绑定在一起,当组件生命周期发生变化处于激活时通知UI更新。这么说可能还有点不清晰,具体请看下文分解:
一、简介
(1)是什么
——LiveData是一个可观察的数据持有者类。与常规的可观察对象不同,LiveData是生命周期感知的,这意味着它尊重其他应用程序组件(如活动、片段或服务)的生命周期。这种意识确保LiveData只更新处于活动生命周期状态的应用程序组件观察者。
(2)有什么用
数据可以被观察者订阅
能够感知组件(Fragment、Activity、Service)的生命周期
只有在组件出于激活状态(STARTED、RESUMED)才会通知观察者有数据更新
(3)有什么优点
能够保证数据和UI统一
减少内存泄漏
当Activity停止时不会引起崩溃
不需要额外的手动处理来响应生命周期的变化
组件和数据相关的内容能实时更新
针对configuration change时,不需要额外的处理来保存数据
资源共享
二、基本使用
(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方法。
四、内容推荐
- 《CSDN》《简书》
- 《Android Jetpack架构组件之Lifecycle源码分析》
- 《Android Jetpack架构组件之Lifecycle入门》
- 《Android Espresso入门到自动搞定》
- 《Android ButterKnife入门到放弃》
五、项目参考
本文相关代码及Demo都放在下面项目中。有兴趣可体验一把
若您发现文章中存在错误或不足的地方,希望您能指出!