android - 初入RX,有一个需求不知道咋写?
PHP中文网
PHP中文网 2017-04-17 17:51:31
0
2
454

需求是这样的:我需要开启一个定时器A,当A定时到50秒的时候,开始开启第二个定时器B,A结束,B开始倒数10秒,每一秒发出一个通知:
然后,我用RX这样做了:

Observable<Long> observable =
                Observable
                        .timer(50, TimeUnit.SECONDS)
                        .repeat(10)
                        .delay(1,TimeUnit.SECONDS);

        subscription = observable
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(aLong -> {
                    //发通知倒计时
                    Log.e("note","flag");
                });

想了半天,好像没啥问题,但是跑起来就有问题了,发现,50秒时挺准的,然后到了第二个定时器,也就是.repeat(10),最后打印的,按照理想,应该是每隔一秒打印,但是实际上相隔了好多秒!。。。
找了半天也没找出啥,难道是我理解错误这几个操作符了?求救大神!

PHP中文网
PHP中文网

认证0级讲师

reply all(2)
小葫芦

1.repeat is repetition, not repeated at a fixed interval. For fixed intervals, use interval
2.delay is to delay the release. Adding delay after repeat means repeating after delay, rather than repeating at intervals according to the delay parameter
3. The solution is to use interval, which can specify the initial delay and repetition interval, plus take and map operations, take the first 10 and convert them into a countdown

Observable.interval(50, 1, TimeUnit.SECONDS)//延迟50s,然后每1秒重复
          .take(10)//取10个
          .map(aLong -> 10 - aLong)//转换成倒计时
          .subscribe(YOUR_ACTION);
大家讲道理

Haven’t found out the reason yet, but I found an alternative version:

/**
     * 倒计时,倒计 time 秒
     * @param time  单位:秒
     * @return  Observable
     */
    public static Observable<Integer> countDown(int time) {
        if (time < 0) time = 0;
        final int countTime = time;
        return Observable.interval(0, 1, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.newThread())
                .map(increaseTime -> countTime - increaseTime.intValue())
                .take(countTime + 1);
    }

This is a countdown, and then just add a delay in front:

private final static int TheMaxRecordTime = 60;     //最大录音时长:秒
private final static int NoteUserRecordTime = 10;   //剩余多少秒开始提示用户
 Observable<Integer> observable = Observable
                .timer(TheMaxRecordTime-NoteUserRecordTime+2, TimeUnit.SECONDS)
                .flatMap((aLong -> RxUtils.countDown(NoteUserRecordTime)));

        subscription = observable
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(aLong -> {
                    setLeftTime(aLong);
                    if (aLong==0)
                        EventBus.getDefault().post(new EventMsg(EventMsg.MessageType.Record_Time_Out));
                });
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template