该方法从远程端startPositionInfoPolling
每 2 秒执行一次轮询PositionInfo
并更新 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();
}