2017-09-20 66 views
1

我有一个列表要刷新每分钟。 例如,用户列表在这里:https://github.com/android10/Android-CleanArchitecture/blob/master/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserList.javaRxJava轮询+手动刷新

我添加使用repeatWhen定期刷新:

public Observable<List<User>> buildUseCaseObservable(Void unused) { 
    return this.userRepository 
     .users() 
     .repeatWhen(new Function<Observable<Object>, ObservableSource<?>>() { 
      @Override 
      public ObservableSource<?> apply(Observable<Object> objectObservable) throws Exception { 
      return objectObservable.delay(1, TimeUnit.MINUTES); 
      } 
     }); 
    } 

它工作正常,这样一来,调用onNext每一分钟。 但是,如果我想立即刷新此列表(因为用户的行为或通知),我不知道如何执行该操作。

我应该取消/处置observable并重新启动一个新的? 感谢

回答

1

从你的代码我明白,用户列表生成和发射订阅。

这里有一些解决方案,我能想到的,而不是退订,并根据事件重新订阅要立即作出反应,其中:

  1. 除了使用repeatWhen运营商,使用interval creation operatorflatMap结合每分钟调用一次新的Observable订阅,并使用merge运算符来添加对您感兴趣的其他事件的反应。事情是这样的:

    @Test 
    public void intervalObservableAndImmediateReaction() throws InterruptedException { 
        Observable<String> obs = Observable.interval(1, TimeUnit.SECONDS) 
           .cast(Object.class)           
           .mergeWith(
              Observable.just("mockedUserClick") 
                .delay(500, TimeUnit.MILLISECONDS)) 
           .flatMap(
             timeOrClick -> Observable.just("Generated upon subscription") 
             ); 
    
        obs.subscribe(System.out::println); 
        Thread.currentThread().sleep(3000); //to see the prints before ending the test 
    } 
    

    或调整,以您的需求(但主要是相同的):

    Observable.interval(1, TimeUnit.MINUTES) 
          .mergeWith(RxView.clicks(buttonView)) 
          .flatMap(timeOrClick -> this.userRepository.users()); 
    
  2. 您可以像以前一样使用flatMap操作,即使让你工作电流实现和没有合并到一个区间 - 只是保持您的工作代码,并在程序链的另一个区域它到您选择的RxBinding

    RxView.touches(yourViewVariable) 
         .flatMatp(motionEvent -> this.userRepository.users()) 
         .subscribe(theObserver); 
    

    请注意,在此解决方案中,订阅是独立于两个可观察对象完成的。如果您使用不同的观察员,或者管理该主题或某项内容,您可能会变得更好。我运行的一个小测试显示,一个订阅者处理订阅了2个不同的观察对象(没有问题)(在Rxjava1中 - 没有检查Rxjava2),但是它对我来说会感觉不舒服。

+0

使用interval和mergeWith似乎很有趣,谢谢。我如何手动触发“刷新”(而不是使用RxView)? –

+0

您可以使用主题,只需从程序中的任何位置调用它的'onNext'即可。 –

1

如果你不关心其他观测的一个调整后的刷新时间发出的数据,你可以这样做以下:

// Specific example of a user manually requesting 
    val request = Observable.create<String> { emitter -> 
     refresh.setOnClickListener { 
      emitter.onNext("Click Request") 
     } 
    } 
      .observeOn(Schedulers.io()) 
      .flatMap { 
       userRepository.users() 
      } 

    // Refresh based off of your original work, could use something like interval as well 
    val interval = userRepository.users() 
      .subscribeOn(Schedulers.io()) 
      .repeatWhen { objectObservable -> 
       objectObservable.delay(1, TimeUnit.MINUTES) 
      } 

    // Combine them so that both emissions are received you can even add on another source 
    Observable.merge(request,interval) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe({ 
       contents.text = it.toString() 
      }, { 
       contents.text = it.toString() 
      },{ 
       println(contents.text) 
      }) 

然后,你不必部署和重新订阅每一次