最近简单看了下google推出的框架Jetpack,感觉此框架的内容可以对平时的开发有很大的帮助,也可以解决很多开发中的问题,对代码的逻辑和UI界面实现深层解耦,打造数据驱动型UI界面。
Android Architecture组件是Android Jetpack的一部分,它们是一组库,旨在帮助开发者设计健壮、可测试和可维护的应用程序,包含一下组件:
上述时Android Architecture所提供的架构组件,本文主要从使用和源码的角度了解一下LiveData组件
class TestViewModel : ViewModel() {
var mCurrent: MutableLiveData? = null
get() {
if (field == null) {
field = MutableLiveData()
}
return field
}
}
//创建观察者对象
val nameObservable = Observer { // 创建观察者对象
textView.text = it // 定义onChange()方法中的操作
}
// 如果在View Model中使用,先创建ViewModel的对象
mModel = ViewModelProviders.of(this).get(TestViewModel::class.java)
// mCurrent 订阅观察
mModel.mCurrent!!.observe(this, nameObservable)
// 设置两个点击事件,修改LiveData中的数据
btnChange.setOnClickListener { mModel.mCurrent!!.value = "AAAAA" }
btnB.setOnClickListener { mModel.mCurrent!!.value = "BBBBB" }
// 将返回开始示例中的 mCurrent 值的长度
var liveDataMap: LiveData = Transformations.map(mCurrent) { input: String -> input.length }
var livaDataSwich : LiveData = Transformations.switchMap(mCurrent){
input: String? -> MutableLiveData().also { it.value = input!!.toLowerCase() }
}
val lowObservable = Observer {
textViewLow.text = it
}
val lengthObservable = Observer {
textViewLength.text = it.toString()
}
mModel.liveDataMap.observe(this, lengthObservable)
mModel.livaDataSwich.observe(this, lowObservable)
public class LocationLiveData extends LiveData {
private static LocationLiveData sInstance;
private LocationManager locationManager;
@MainThread
public static LocationLiveData get(Context context) {
if (sInstance == null) {
sInstance = new LocationLiveData(context.getApplicationContext());
}
return sInstance;
}
private SimpleLocationListener listener = new SimpleLocationListener() {
@Override
public void onLocationChanged(Location location) {
setValue(location);
}
};
private LocationLiveData(Context context) {
locationManager = (LocationManager) context.getSystemService(
Context.LOCATION_SERVICE);
}
@Override
protected void onActive() {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
}
@Override
protected void onInactive() {
locationManager.removeUpdates(listener);
}
}
上面代码使用单例提供LocationLiveData可以在Activity和Fragment之间实现共享,在onActive和onInactive中完成监听的注册和取消,当位置改变时回调Listener并调用setValue()设置LiveData的值,从而自动更新观察者中的数据,其实前面使用的MutableLiveData也是同样的一个扩展
扩展的LiveData使用和正常使用一样,observe()方法将Fragmrnt(它是一个实例LifecycleOwner)作为第一个参数传递,使观察者绑定到Fragment的生命周期,如果Lifecycle对象未处于活动状态,则即使值发生更改,也不会调用观察者,在之后Lifecycle的对象被Destroy后,观察者被自动删除
public class MutableLiveData extends LiveData {
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
从代码中可以看出MutableLiveData知识LiveData的一个扩展类,重写了LiveData中的抽象方法,postValue()和setValue()中也只是调用了super.postValue()和super.setValue(),也就是说所有的方法都是在LiveData中实现,
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
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);
}
从第一步添加观察者observe方法开始,从参数中看到了LifecycleOwner,相信看过Lifecycler源码的(Android Jetpack框架之 Lifecycle(源码篇))应该会想到这里的作用是处理生命周期改变,在observe方法中执行了以下逻辑:
private abstract class ObserverWrapper {
final Observer mObserver;
ObserverWrapper(Observer observer) {
mObserver = observer; // 保存观察者Observer
}
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
mActive = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) {
onActive(); // 当Owner为活跃状态时回调onActive()
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive(); // 当Owner未活跃状态时回调onInactive()
}
if (mActive) {
dispatchingValue(this);
}
}
}
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver { //
@NonNull final LifecycleOwner mOwner; //保存LifecycleOwner
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer observer) {
super(observer); // 调用父类ObserverWrapper的构造函数传递Owner
mOwner = owner;
}
// 实现GenericLifecycleObserver 当生命周期改变时回调onStateChanged
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver); // DESTROYED时移除观察者
return;
}
activeStateChanged(shouldBeActive());
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
上述执行的逻辑见代码中的注释,ObserverWrapper 在Owner活跃状态改变时回调onActive和onInactive方法,LifecycleBoundObserver主要利用Lifecycler的生命周期观察者GenericLifecycleObserver,前面设置了owner.getLifecycle().addObserver(wrapper)后,当生命周期改变时会回调onStateChange()方法,在生命周期为Destroy时移除Observer;
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
private void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
for (Iterator, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
}
setValue()中调用了dispatchingValue(),在dispatchingValue中遍历mObservers中所有的Observer,调用considerNotify()更新数据
private void considerNotify(ObserverWrapper observer) {
observer.mObserver.onChanged((T) mData);
}
considerNotify()中调用mObserver的onChange()方法,这里的mObserver就是前面observe()中第二个参数的Observer,从而更新数据,简单就是说当LiveData中的数据改变时会遍历此LiveData所有的观察者,并回调onChange(),所以所有注册观察此数据的地方都会改变
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;
}
//noinspection unchecked
setValue((T) newValue);
}
};
postValue()其实是在非主线程中更新数据,其实他传递的Runnable中也是调用了setValue()方法,其余的操作只是通过ArchTaskExecutor和DefaultTaskExecutor将操作切换到主线程。
LiveData的使用和源码分析到此结束了,LiveData整个过程就是两部分,一是使用LifeCycleOwner感知声明周期的变化,两一个就是储存并遍历Observer,在数据改变时回调所有的观察者,LiveData的实现还是比较简单的,希望本篇文章的分析对大家有所帮助。