我发现了一个非常有趣的案例,你必须根据它发出的数据更改初始Observable
。
我有LocationManager
,它提供的位置在更新之间有不同的间隔。
enum LocationUpdateFrequency {
HEIGHT, MEDIUM, LOW
}
interface LocationManager {
Observable<Location> getLocationUpdates(LocationUpdateFrequency frequency);
LocationUpdateFrequency calcOptimalFrequency(Location currentLocation, Location prevLocation);
}
所以我想订阅默认值为MEDIUM的初始getLocationUpdates,在它生成2个位置之后,我想重新订阅新的最佳频率。
我有一个解决方案,但它使用可变性:
class LocationState {
Location currentLocation;
Location pastLocation;
boolean isValid() {
return currentLocation != null && pastLocation != null;
}
}
class LocationAndFrequency {
final Location location;
final LocationUpdateFrequency frequency;
public LocationAndFrequency(Location location, LocationUpdateFrequency frequency) {
this.location = location;
this.frequency = frequency;
}
}
public Observable<Location> getOptimalLocationUpdates() {
final LocationManager locationManager = null;
final LocationState state = new LocationState();
return Observable.defer(() -> {
final LocationUpdateFrequency frequency;
if (state.isValid()) {
frequency = locationManager.calcOptimalFrequency(state.currentLocation, state.pastLocation);
} else {
frequency = LocationUpdateFrequency.MEDIUM;
}
return locationManager.getLocationUpdates(frequency)
.doOnNext(location -> {
state.pastLocation = state.currentLocation;
state.currentLocation = location;
})
.map(location -> new LocationAndFrequency(location, frequency));
})
.takeUntil(locationAndFrequency -> {
final LocationUpdateFrequency optimalFrequency =
locationManager.calcOptimalFrequency(state.currentLocation, state.pastLocation);
return locationAndFrequency.frequency != optimalFrequency;
})
.map(locationAndFrequency -> locationAndFrequency.location)
.repeat();
}
什么是更优雅的解决方案?