方法startPositionInfoPolling
从远程端执行PositionInfo
的每2秒轮询并更新UI。
private Subscription mPollingTimerSubscription;
private Observable<Long> mPollingTimerObservable = Observable.timer(0, 2, TimeUnit.SECONDS);
private void startPositionInfoPolling() {
LOGGER.trace("...");
mPollingTimerSubscription = mPollingTimerObservable
.flatMap(new Func1<Long, Observable<PositionInfo>>() {
@Override
public Observable<PositionInfo> call(Long ticker) {
LOGGER.debug("XXX ticker = {}", ticker);
return mMediaRendererClient.createPositionInfoObservable();
}
})
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<PositionInfo>() {
@Override
public void call(final PositionInfo positionInfo) {
LOGGER.debug("XXX positionInfo = {}", positionInfo);
mMusicMediaTrackDetailsFragment.updateView(updatedPositionInfo);
}
});
}
方法stopPositionInfoPolling
停止了UI更新。
private void stopPositionInfoPolling() {
LOGGER.trace("...");
mPollingTimerSubscription.unsubscribe();
}
我想更改代码,以便更少定期(例如每20秒)获取远程数据,并定期(例如每1秒)使用外推值更新UI。
我使用RxJava的第一个解决方案如下:
private Subscription mPollingTimerSubscription, mUpdatingTimerSubscription;
private Observable<Long> mPollingTimerObservable = Observable.timer(0, 20, TimeUnit.SECONDS);
private Observable<Long> mUpdatingTimerObservable = Observable.timer(0, 1, TimeUnit.SECONDS);
private void startPositionInfoPolling() {
LOGGER.trace("...");
mPollingTimerSubscription = mPollingTimerObservable
.subscribe(new Action1<Long>() {
@Override
public void call(Long ticker) {
LOGGER.debug("XXX ticker = {}", ticker);
mMediaRendererClient.createPositionInfoObservable()
.retry(2)
.subscribe(new Action1<PositionInfo>() {
@Override
public void call(final PositionInfo positionInfo) {
LOGGER.debug("XXX positionInfo = {}", positionInfo);
mUpdatingTimerSubscription = mUpdatingTimerObservable
.take(20, TimeUnit.SECONDS)
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Long>() {
@Override
public void call(Long ticker) {
LOGGER.debug("XXX ticker = {}", ticker);
String updatedRelTime = ModelUtil.toTimeString(ModelUtil.fromTimeString(positionInfo.getRelTime()) + ticker);
PositionInfo updatedPositionInfo = new PositionInfo(positionInfo, updatedRelTime, positionInfo.getAbsTime());
LOGGER.debug("XXX positionInfo = {}", updatedPositionInfo);
mMusicMediaTrackDetailsFragment.updateView(updatedPositionInfo);
}
});
}
});
}
});
}
private void stopPositionInfoPolling() {
LOGGER.trace("...");
mPollingTimerSubscription.unsubscribe();
mUpdatingTimerSubscription.unsubscribe();
}
有人可以帮助我将这段代码转换成更少回调的东西吗?!我认为flatMap
是关键,但我的思想仍然没有被动反应; - )
另一个问题是mPollingTimerSubscription.unsubscribe();
没有取消订阅/取消/停止mUpdatingTimerObservable
,因此正在维护另一个订阅。
提前感谢任何评论。
更新:感谢@hello_world减少原有的复杂性; - )
private Subscription mPollingTimerSubscription, mUpdatingTimerSubscription;
private Observable<Long> mPollingTimerObservable = Observable.timer(0, 20, TimeUnit.SECONDS);
private Observable<Long> mUpdatingTimerObservable = Observable.timer(0, 1, TimeUnit.SECONDS);
private void startPositionInfoPolling() {
LOGGER.trace("...");
mPollingTimerSubscription = mPollingTimerObservable
.flatMap(new Func1<Long, Observable<PositionInfo>>() {
@Override
public Observable<PositionInfo> call(Long ticker) {
LOGGER.debug("XXX ticker = {}", ticker);
return mMediaRendererClient.createPositionInfoObservable();
}
})
.retry(2)
.subscribe(new Action1<PositionInfo>() {
@Override
public void call(final PositionInfo positionInfo) {
LOGGER.debug("XXX positionInfo = {}", positionInfo);
mUpdatingTimerSubscription = mUpdatingTimerObservable
.take(20, TimeUnit.SECONDS)
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Long>() {
@Override
public void call(Long ticker) {
LOGGER.debug("XXX ticker = {}", ticker);
String updatedRelTime = ModelUtil.toTimeString(ModelUtil.fromTimeString(positionInfo.getRelTime()) + ticker);
PositionInfo updatedPositionInfo = new PositionInfo(positionInfo, updatedRelTime, positionInfo.getAbsTime());
LOGGER.debug("XXX positionInfo = {}", updatedPositionInfo);
mMusicMediaTrackDetailsFragment.updateView(updatedPositionInfo);
}
});
}
});
}
private void stopPositionInfoPolling() {
LOGGER.trace("...");
mPollingTimerSubscription.unsubscribe();
mUpdatingTimerSubscription.unsubscribe();
}
答案 0 :(得分:0)
经过与@hello_world的一些讨论和一些思考之后,两个带时间戳的观察者的组合观察似乎完成了这项工作。 确实非常强大的概念,但由于Java语法,它有点丑陋的代码。
private Subscription mPollingAndUpdatingTimerSubscription;
private Observable<Long> mPollingTimerObservable = Observable.timer(0, 20, TimeUnit.SECONDS);
private Observable<Long> mUpdatingTimerObservable = Observable.timer(0, 1, TimeUnit.SECONDS);
private void startPositionInfoPolling() {
LOGGER.trace("...");
Observable<Timestamped<PositionInfo>> timestampedPositionInfoObservable =
mPollingTimerObservable
.flatMap(new Func1<Long, Observable<PositionInfo>>() {
@Override
public Observable<PositionInfo> call(Long ticker) {
LOGGER.debug("XXX ticker = {}", ticker);
return mMediaRendererClient.createPositionInfoObservable();
}
})
.retry()
.timestamp();
Observable<Timestamped<Long>> timestampedUpdateObservable = mUpdatingTimerObservable.timestamp();
Observable<PositionInfo> combinedPositionInfoObservable = Observable.combineLatest(
timestampedPositionInfoObservable,
timestampedUpdateObservable,
new Func2<Timestamped<PositionInfo>, Timestamped<Long>, PositionInfo>() {
@Override
public PositionInfo call(Timestamped<PositionInfo> timestampedPositionInfo, Timestamped<Long> timestampedUpdate) {
PositionInfo orgPositionInfo = timestampedPositionInfo.getValue();
long delayInMillis = timestampedUpdate.getTimestampMillis() - timestampedPositionInfo.getTimestampMillis();
LOGGER.debug("XXX delayInMillis = {}", delayInMillis);
String updatedRelTime = DurationUtil.format(DurationUtil.parse(orgPositionInfo.getRelTime()).getTime() + delayInMillis);
return new PositionInfo(orgPositionInfo, updatedRelTime, orgPositionInfo.getAbsTime());
}
});
mPollingAndUpdatingTimerSubscription =
combinedPositionInfoObservable
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<PositionInfo>() {
@Override
public void call(final PositionInfo positionInfo) {
LOGGER.debug("XXX positionInfo = {}", positionInfo);
mMusicMediaTrackDetailsFragment.updateView(positionInfo);
}
});
}
private void stopPositionInfoPolling() {
LOGGER.trace("...");
mPollingAndUpdatingTimerSubscription.unsubscribe();
}