2014-12-11 10 views
0

나는 다음과 같은 방식으로 유지 보수 작업을 위해 rxjava을 사용하고와 관찰 가능한 타이머 사용 결과를 방출하는 방법 : 나는 정기적 인 예방 정비가 필요합니다 클래스에서flatMap

을, 나는 관찰 결과 다음과 같은 정적 구독을 사용 클래스가 메모리에로드 될 때 처음 실행되고 지정된 간격으로 시작됩니다.

private static Subscription subscription = Observable.timer(0, 5, TimeUnit.SECONDS) 
     .flatMap(new Func1<Long, Observable<String>>() { 
      @Override public Observable<String> call(Long aLong) { 

       // some code 

       return Observable.just(null); 
      } 
     }).subscribeOn(Schedulers.newThread()).observeOn(Schedulers.newThread()) 
     .subscribe(); 

이제는 유지 관리 결과를 UI에보고하고자하는 상황이 있습니다.

일반적으로, 나는 다음과 같은 스키마를

Observable.create(new Observable.OnSubscribe<String>() { 

     @Override public void call(Subscriber<? super String> subscriber) { 

      // some code 

      subscriber.onNext(result); 
      subscriber.onCompleted();   } 

    }).subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Action1<String>() { 

       @Override public void call(String result) { 

        // write to the UI 

       } 

      }); 

을 사용하지만, 여기에 우리가 한 번만 실행되는 피 감시가 있습니다.

일정한 간격으로 실행되는 Observable의 경우 subscriber.onNext()를 사용하여 결과를 전달할 수 있도록 구독자에서 Action을 호출하는 방법을 찾을 수 없습니다. Observable에 적합한 서명이없는 것 같습니다. timer는 timer()에서 오랜 시간이 걸릴 수 있으며 동시에 작업에 가입 할 수 있습니다. 하지만 rxjava를 알면 트릭을 쓸 수 있습니다 .-)

나는이 작업을 Timer Observable과 Observable (기본적으로 두 버전을 압축)을 사용하여 압축 할 수 있지만, 약간 다른 행동을하기 때문에 첫 번째 구조.

private static Subscription subscription = Observable.timer(0, 5, TimeUnit.SECONDS) 
     .flatMap(new Func1<Long, Observable<String>>() { 
      @Override public Observable<String> call(Long aLong) { 

       // some code // stays here to ensure there is no concurrency while executing 

       final String result = "result"; // I store the result in a final variable after some code has been finished 

       return Observable.create(new Observable.OnSubscribe<String>() { 
        @Override public void call(Subscriber<? super String> subscriber) { 
         subscriber.onNext(result); // then I use it in a new Observable and emit it 
         subscriber.onCompleted(); // not sure if this is needed here (haven't tested this yet) 
        } 
       }); 

      } 
     }).subscribeOn(Schedulers.newThread()).observeOn(Schedulers.newThread()) 
     .subscribe(new Action1<String>() { 
      @Override public void call(String result) { 
       // so I can finally consume the result on the UI thread 
      } 
     }); 

는 대신에 "널 (null)"관찰 가능한을 생성하고 방출, 나는이 하나를 만들 나에게 보낼 수 있습니다 : -

나는 다음과 같은 방식으로 하나에 두 버전을 모두 병합 시도 결과를 구독자에게 보냅니다.

꽤 지저분하지만, 제대로 작동합니까? 더 간단한 해결책? 당신의 생각은 무엇입니까?

+0

왜'Observable.timer.flatMap'가 작동하지 않습니까? – zsxwing

+0

flatMap은 방출 된 Observables를 하나의 Observable (내가 원하는 것)으로 평평하게 만들기 때문에 작동하지 않는다고 생각합니다. 그러나 그걸로 저는 가입자와 인터페이스를 제공하는 서명을 찾지 못합니다 [@Override public void call (Subscriber subscriber)] 그래서 subscriber.onNext()를 사용할 수 있습니다. –

답변

1

나는 당신의 문제를 이해하기가 쉽지 않습니다.

Observable Timer와 다른 Observable에서 같은 구독을 사용 하시겠습니까?

아마도 주제를 사용하여 Observables 사이의 다리 역할을 할 수 있습니다.

Subject<?, ?> bridge = PublishSubject.create(); 
Observable.timer(5, SECONDS).flatMap(/* whatever*/).mergeWith(bridge).subscribe(/* toDo */); 
Observable.create(/* subscription */).subscribe(bridge); 

당신의 "관찰 가능한 한 시간"에 의해 방출 각 항목은 관찰은 "타이머"에 밀어 것 brige를로 밀어됩니다.

찾고 계신가요?

+0

[나는 주제/교량을 한번도 사용하지 않았기 때문에 그것이 작동하는지 말할 수 있기 전에 나는 이것을 읽고 밖으로 시험 할 필요가있다. 나는 잠시 후에 다시 돌아올 것이다.] –

+0

두 코드 스 니펫을 병합 한 위의 버전을 추가했습니다. 테스트가 없으면 이것이 효과가 있어야한다고 생각합니다. PublishSubject를 통해 우리는 좋은 길을 가고 있다고 생각하며, 아마도 내가 위에서 한 것보다 훨씬 간단하게 문제를 해결할 수있을 것입니다.그러나 당신의 설명에서 '각 항목은 당신의 "관찰 가능한 한 시간"에 의해 방출 될 것이고, 그것은 관찰 가능한 "타이머"에 밀어 넣을 것이다. 두 Observables를 결합하고 싶지 않기 때문에 당신이 오해 한 것처럼 보입니다. Timer Observable을 시계로 사용하려는 의도가 있으며 어떤 식 으로든 그 값을 필요로하지 않습니다. –

+0

확인. 어쩌면 다른 관찰 가능 타이머를 압축 할 수 있습니다. 어쨌든, 당신이 트릭을 이해했다고 생각합니다. ;) – dwursteisen

관련 문제