2017-09-20 62 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) 
      }) 

然後,你不必部署和重新訂閱每一次