一、引言
JetPack作为google大力推出的MVVM框架有着其独特的“天之骄子”身份,作为Android系统工程师,自然而然地需要研究一下Jetpack。
作用:
1、LiveData作为JetPack中的数据持有者。
2、主要用于观察数据源发生变化,或者Activity的生命周期发生变化时,通知观察者;
2、并且可以和Activity的生命周期进行绑定,当Activity的生命周期处于onDestroy时,不会通知观察者,从而避免造成内存泄漏。
二、LiveData基本用法
2.1 代码
LiveData的用法很简单,由于LiveData是抽象类,google给出实现类MutableLiveData。调用LiveData的observe传入Activity 和观察者,通过setValue或者postValue方法改变LiveData持有的数据源时,回调observe方法。
public class MainActivity extends AppCompatActivity {
private MutableLiveData<String> liveData = new MutableLiveData<>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* 此处需要传递两个参数
* 1、LifecycleOwner
* 2、Observe
*/
liveData.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
Log.d("kkjj",s);
}
});
}
public void send(View view) {
liveData.postValue("test");
}
}
2.2 setValue和postValue区别
上面说道setValue和postValue都可以改变LiveData持有的数据源,那么他们两个有什么区别呢?
(1)setValue
在LiveData的setValue源码中可以清晰地看到其必须运行在主线程中,否则抛异常
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
private static void assertMainThread(String methodName) {
if (!ArchTaskExecutor.getInstance().isMainThread()) {
throw new IllegalStateException("Cannot invoke " + methodName + " on a background"
+ " thread");
}
}
(2)postValue
postValue中先判断mPendingData == NOT_SET?初始mPendingData 默认为NOT_SET,在最后一句看到将线程切换到主线程中。
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
通过同步的方式将mPendingData = NOT_SET,并且最后还是调用了setValue
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
因此可以得出结论:setValue用于主线程中发送数据,postValue用于子线程中设置数据,postValue最后还是通过将线程切回到主线程中调用setValue设置数据。
三、LiveData原理解析
3.1 observe回调原理
上面例子中第一个参数传入MainActivity是因为ComponentActivity继承与LifecycleOwner。由于原理分支比较多,在注释中标记“分析”标签分别剖析。