LiveData
LiveData是一个用于持有数据并支持数据可被监听(观察)。和传统的观察者模式中的被观察者不一样,LiveData是一个生命周期感知组件,因此观察者可以指定某一个LifeCycle给LiveData,并对数据进行监听。
如果观察者指定LifeCycle处于Started或者RESUMED状态,LiveData会将观察者视为活动状态,并通知其数据的变化。
我们看一段代码:
public class LocationLiveData extends LiveData{
private LocationManager locationManager;
private SimpleLocationListener listener = new SimpleLocationListener() {
@Override
public void onLocationChanged(Location location){
setValue(location);
}
};
public 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);
}
}
上面有三个值得注意的地方:
onActive()
当这个方法被调用时,表示LiveData的观察者数量从0变为了1,这时就我们的位置监听来说,就应该注册我们的时间监听了。
onInactive()
这个方法被调用时,表示LiveData的观察者数量变为了0,既然没有了观察者,也就没有理由再做监听,此时我们就应该将位置监听移除。
setValue()
通过调用这个方法来更新LiveData的数据,并通知处于活动状态的观察者。
接着我们就能像下面这样使用LocationLiveData了。
public class MyFragment extends LifecycleFragment{
public void onActivityCreated (Bundle savedInstanceState){
LiveData myLocationListener = ...;
Util.checkUserStatus(result -> {
if (result) {
myLocationListener.addObserver(this, location -> {
// update UI
});
}
});
}
}
注意上面的addObserver方法,我们将LifeCycleOwner作为第一个参数传递了进去,这表示我们的LocationLiveData将遵照这个Fragment所持有的LifeCycle办事。
如果LifeCycle不在Started或者RESUMED这两个状态,那么观察者将无法接受到数据更新的回调,即使数据发生了变化。
如果LifeCycle销毁了,即生命周期结束,观察者将被自动从LiveData中移除。
既然LocationLiveData是生命周期感知的,那么我们就可以稍微改动一下它的代码,让它可以被多个Activity或者Fragment公用:
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);
}
}
这里使用单例的原因就是让多个Activity或者Fragment共享一个LocationLiveData实例。
然后我们可以这么使用: