上一篇文章,学习了Android官方架构组件的第一部分Android进阶 ——— Android官方架构组件Lifecycle
初探
LiveData 是一个可以感知 Activity 、Fragment生命周期的数据容器。当 LiveData 所持有的数据改变时,它会通知相应的界面代码进行更新。同时,LiveData 持有界面代码 Lifecycle 的引用,这意味着它会在界面代码(LifecycleOwner)的生命周期处于 started 或 resumed 时作出相应更新,而在 LifecycleOwner 被销毁时停止更新。
- 意味着LiveData可以被观察者订阅,并且感知LifeCycleOwner组件的生命周期。
- 如果
LifecycleOwner
的状态为Lifecycle.State.STARTED
或Lifecycle.State.RESUMED
,才会通知观察者更新- 可以通过
observeForever(Observer)
添加的观察者,使其始终处于活动状态,不仅仅是处于活跃状态。但是这种方式添加的观察者,需要手动调用removeObserver(Observer)
解除
上面的描述介绍了LiveData的优点:不用手动控制生命周期,不用担心内存泄露,数据变化时会收到通知。
不仅如此,官方推荐,LiveData和Viewmodel搭配使用,ViewModel是Android官方构件的另一成员。
ViewModel 将视图的数据和逻辑从具有生命周期特性的实体(如 Activity 和 Fragment)中剥离开来。直到关联的 Activity 或 Fragment 完全销毁时,ViewModel 才会随之消失,也就是说,即使在旋转屏幕导致 Fragment 被重新创建等事件中,视图数据依旧会被保留。ViewModels 不仅消除了常见的生命周期问题,而且可以帮助构建更为模块化、更方便测试的用户界面。
ViewModel的优点:为Activity 、Fragment存储数据,直到完全销毁。尤其是屏幕旋转的场景,常用的方法都是通过onSaveInstanceState()保存数据,再在onCreate()中恢复,真的是很麻烦。
其次因为ViewModel存储了数据,所以ViewModel可以在当前Activity的Fragment中实现数据共享。
使用
LiveData有几种使用方式:
- 使用LiveData对象
- 继承LiveData
1.使用LiveData对象
使用LiveData对象主要有以下几个步骤:
- 创建保存特定数据类型的LiveData实例(ViewModel中);
- 创建Observer对象,作为参数传入LiveData.observe()方法,添加观察者;
- 通过 observe()方法连接观察者和LiveData。observe()方法需要携带一个LifecycleOwner类。这样就可以让观察者订阅LiveData中的数据;
创建LiveData实例,一般继承自MutableLiveData
MutableLiveData是LiveData的子类,添加了公共方法setValue和postValue,方便开发者直接使用。setValue必须在主线程调用。postValue可以在后台线程中调用。
/**
* Created by dai
* Created time 2018/8/20
* function:lifecycle.example.com.lifecycleexample.LifeCycle
*/
public class MainViewModel extends ViewModel{
private MutableLiveData<Student> student = new MutableLiveData<>();
public MutableLiveData<Student> getStudent() {
return student;
}
public void addStudent(){
Student student1 = new Student();
student1.setGender(55);
student1.setName("zhangsan");
student.setValue(student1);
}
}
创建Observer对象,作为参数添加观察者
通过LiveData.observe()方法添加观察者,当数据变化时会通过回调方法通知观察者
/**
* Created by dai
* Created time 2018/8/20
* function:lifecycle.example.com.lifecycleexample
*/
public class MainActivity extends AppCompatActivity {
private MainPresenter presenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
presenter = new MainPresenter();
getLifecycle().addObserver(presenter);
final TextView textView = findViewById(R.id.text);
Button button = findViewById(R.id.button);
ViewModelProvider.NewInstanceFactory factory = new ViewModelProvider.NewInstanceFactory();
final MainViewModel model = factory.create(MainViewModel.class);
//订阅数据变化
model.getStudent().observe(this, new Observer<Student>() {
@Override
public void onChanged(@Nullable Student student) {
textView.setText(student.getName());
Log.e(student.getName(),student.getGender() + "年级");
}
});
}
更新LiveData中的数据
点击button,修改LiveData数据,观察者观察到数据变化,打印出信息
//修改数据
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
model.addStudent();
}
});
}
2.继承LiveData
在LiveData中,onActive方法回调表明当前Activity处于激活状态,也就是Activity处于生命周期的活动状态中(onStart,onResume),可以简单认为当前的Activity处于前台。LiveData的onInactive处理涉及onActive剩下的生命周期
1)创建继承于MutableLiveData
自定义一个MyThread继承MutableLiveData,内部实现一个简单的功能,后台运行一个长时的线程任务,该线程实现一个简单功能:
(1)如果当前的Activity处于运行(用户可见)状态,则线程任务不断累计计数器并postValue一个值给任何Observer使用。
(2)如果当前Activity处于没有激活状态,则暂停线程任务,停止累计计数器。
/**
* Created by dai
* Created time 2018/8/21
* function:lifecycle.example.com.lifecycleexample
*/
public class MyThread extends MutableLiveData<Integer> {
private Integer a = 0;
private boolean Active = true;
private Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (Active){
a++;
postValue(a);
}
}
});
public MyThread(){
thread.start();
}
@Override
protected void onInactive() {
super.onInactive();
Log.e("aa","onInactive");
Active = false;
}
@Override
protected void onActive() {
super.onActive();
Log.e("aa","onActive");
Active = true;
thread.interrupt();
}
}
2)构建Observer
再构建Observer,在Observer的onChanged中监听变化
在LiveData中的数据变化,通过postValue(可后台线程)或者setValue(主线程)设置后,将触发Observer的onChanged,开发者只需onChanged等待最新数据回调即可。
public class MainActivity extends AppCompatActivity {
private MainPresenter presenter;
private TextView textView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.text);
MyThread thread = new MyThread();
thread.observe(this,new MyObserver());
}
private class MyObserver implements Observer<Integer> {
@Override
public void onChanged(@Nullable Integer number) {
Log.e("Main",number.intValue()+"");
textView.setText(number.toString());
}
}
}
LiveData原理
先来熟悉一下类图,再分源码
这里参考一下Android架构组件(二)——LiveData
类关系图
LiveData的类关系图相对比较简单,从上面的类图我们就能看到。和LiveData组件相关的类和接口有:LiveData类、Observer接口、GenericLifecycleObserver接口。
LiveData类是个抽象类,但是它没有抽象方法,抽象类有个特点是:不能在抽象类中实例化自己。为什么LiveData会被定义成abstract而又没有抽象方法呢,这个…我也不知道,看了下LiveData的提交记录,是在将hasObservers()替换getObserverCount()方法时将LiveData改成了abstract,在此之前它是被定义为public,可以翻墙的可以看下这里的修改记录
MediatorLiveData继承自MutableLiveData,MutableLiveData继承自LiveData。MediatorLiveData可以看成是多个LiveData的代理,当将多个LiveData添加到MediatorLiveData,任何一个LiveData数据发生变化时,MediatorLiveData都会收到通知。
LiveData有个内部类LifecycleBoundObserver,它实现了GenericLifecycleObserver,而GenericLifecycleObserver继承了LifecycleObserver接口。在这里可以回顾下Lifecycle组件相关的内容。当组件(Fragment、Activity)生命周期变化时会通过onStateChanged()方法回调过来。
Observer接口就是观察者,其中定义了LiveData数据变化的回调方法onChanged()。
时序图
LiveData主要涉及到的时序有三个:
- 在Fragment/Activity中通过LiveData.observer()添加观察者(observer()方法中的第二个参数)。
- 根据Fragment/Activity生命周期发生变化时,移除观察者或者通知观察者更新数据。
- 当调用LiveData的setValue()、postValue()方法后,通知观察者更新数据。
最让人头疼的源码,这里只抽取出常用方法
//添加观察者,普通模式,只在LifecycleOwner处于活跃状态,监听LiveData的变化
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//将LifecycleOwner对象和Observer对象封装成LifecycleBoundObserver对象。
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
// mObservers可以理解成一个类似Map的容器,putIfAbsent()方法是判断容器中的observer(key)
// 是否有已经和wrapper(value)关联,如果已经关联则返回关联值,否则关联并返回wrapper。
LifecycleBoundObserver existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && existing.owner != wrapper.owner) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
owner.getLifecycle().addObserver(wrapper);
//条件LifecycleOwner的生命周期观察者
}
/**通过observeForever()添加观察者,观察者会一直受到数
据的变化回到,而不是在组件处于STARTED和RESUMED状态下才
会收到,因为这是LifecycleOwner对象就不再是组件了,而是
ALWAYS_ON;另外通过该方法添加观察者后,要手动调用
removeObserver()方法来停止观察者接收回调通知。
observeForever()方法体很简单,调用了observe()方法
,传入的一个参数是ALWAYS_ON常量
*/
@MainThread
public void observeForever(@NonNull Observer<T> observer) {
}
/**移除观察者,如果不是主线程,则会警告,然后根据
observer取出对应的ObserverWrapper(SafeIterableMap中存储Observer和
ObserverWrapper),真正实现移除是在
removed.activeStateChanged(false)中
*/
@MainThread
public void removeObserver(@NonNull final Observer<T> observer) {
assertMainThread("removeObserver");
//mObservers是一个SafeIterableMap对象
ObserverWrapper removed = mObservers.remove(observer);
if (removed == null) {
return;
}
removed.detachObserver();
//真正移除Observer的监听
removed.activeStateChanged(false);
}
/**
移除全部观察者,同样必须主线程,然后遍历所有Observer,调用removeObserver移除Observer
*/
@MainThread
public void removeObservers(@NonNull final LifecycleOwner owner) {
assertMainThread("removeObservers");
for (Map.Entry<Observer<T>, ObserverWrapper> entry : mObservers) {
if (entry.getValue().isAttachedTo(owner)) {
removeObserver(entry.getKey());
}
}
}
//主/分线程都可以调用,如果主线程多次调用,只调度最后一个值
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
// 会在主线程中执行 mPostValueRunnable中的内容。
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
//判断主线程,
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
//获取数据,很简单
public T getValue() {
Object data = mData;
if (data != NOT_SET) {
//noinspection unchecked
return (T) data;
}
return null;
}
//活跃状态,空方法,子类实现
protected void onActive() {
}
//非活跃状态,空方法,子类实现
protected void onInactive() {
}
//是否有观察者
public boolean hasObservers() {
return mObservers.size() > 0;
}
//是否有活跃观察者
public boolean hasActiveObservers() {
return mActiveCount > 0;
}
private abstract class ObserverWrapper {
final Observer<T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<T> observer) {
mObserver = observer;
}
abstract boolean shouldBeActive();
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
void detachObserver() {
}
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
//是否有活跃状态的观察者
boolean wasInactive = LiveData.this.mActiveCount == 0;
//增加或减少活跃状态观察者数量
LiveData.this.mActiveCount += mActive ? 1 : -1;
//存在活跃状态观察者且新增观察者,则是活跃状态
if (wasInactive && mActive) {
onActive();
}
//如果活跃状态观察者为0,且移除观察者,则非活跃状态
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();
}
if (mActive) {
dispatchingValue(this);
}
}
}
总结
简单了解LiveData的使用以及原理,发现内部并不太复杂,一直是维护一个观察者和观察者管理对象的 SafeIterableMap,现在就可以在轻松的开始尝试了。