我正在使用reactive-location lib。
我的用例是我有一个从observable发出的对象流。这些物品可能每隔几个小时发出一次。一旦项目被发出,我想获得一个位置并使用zipWith(据我所知)发出一个包含该位置的对象。
问题是:由于物体每隔几个小时才会被发射一次,我无法保持位置可观察到热,因为它会耗尽电池。
所以我需要以下内容:一旦将对象传递到流中,一旦获得位置就订阅可观察的位置,取消订阅可观察的位置。这必须不断完成。
据我了解,此转换器负责取消订阅
public <T> Observable.Transformer<T, T> takeNextAndUnsubscribe() {
return new Observable.Transformer<T, T>() {
@Override
public Observable<T> call(Observable<T> tObservable) {
final BehaviorSubject subject = BehaviorSubject.create();
Observable source = tObservable.doOnNext(new Action1<T>() {
@Override
public void call(T t) {
subject.onNext(t);
}
});
return Observable
.merge(source.takeUntil(subject), subject)
.take(1);
}
};
}
但是,如果在流中向下发送新对象,我将如何再次订阅?
答案 0 :(得分:1)
您需要的是将源项目与发布时的当前位置相结合。这里不需要任何花哨的东西。只需在每个源项目上使用flatMap()
即可将其与位置相结合。
source.flatMap(item ->
locationProvider
.getLastKnownLocation()
.map(location -> new ItemWithLocation<>(item, location))
);
class ItemWithLocation<T> {
private final T item;
private final Location location;
public ItemWithLocation(T item, Location location) {
this.item = item;
this.location = location;
}
public T getItem() {
return item;
}
public Location getLocation() {
return location;
}
}
编辑:更新了第二个示例。以下内容将订阅位置更新,直到达到特定的准确度,然后将其与源项目合并。这里的关键是使用first()
。只要您获得满足您需求的位置,使用它将取消订阅位置提供商。
LocationRequest request =
LocationRequest
.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(100);
source.flatMap(item ->
locationProvider
.getUpdatedLocation(request)
.first(location -> location.getAccuracy() < 5.0f)
.map(location -> new ItemWithLocation<>(item, location))
);