2016-06-09 3 views
6

나는 불을 매우 오랜 시간이 걸리지 않는 작업을 잊지하지만 난 반응 적 백그라운드에서 실행할 싶다고 충분히. 수명은 기본적으로 서버에 연결되어 있거나 10 초가 지났습니다. 나는 올바른 라이프 사이클을 유지하면서 효율적으로 청소할 수 있도록 이들을 보관하는 방법을 모른다.RxJava를 정리하고 구독을 잊어 버리는 방법은 무엇입니까?

Subscription fireAndForget = service.doSomething() 
            .timeout(10, TimeUnit.SECONDS) 
            .subscribe(() -> { 
             otherService.doAction() 
            }, (e) -> { Log.e("error", e) }); 
// what do I do with fireAndForget??? 

// If I use a CompositeSubscription 
subscriptions.add(fireAndForget) // how does it get removed???? 
그때 작업이 완료 될 때 내가 그들을 지우 어떻게 그것들을 보유하고 계속 내 연결에 CompositeSubscription을 가지고 있지만 수

? 구독이 구독을 취소 할 때 CompositeSubscription을 삭제해야합니까? 나는 Rx에 상대적으로 새롭기 때문에 Rx가 의도 한 바가 아닌 무언가를하려고하는지 확실하지 않습니다.

답변

4

힌트 : 당신이 주변에 가입을 유지하는 경우 화재 및

당신은 잊고되지 않습니다 잊어 버려. 구독을하고 이동하십시오.

service.doSomething() 
    .timeout(10, TimeUnit.SECONDS) 
    .subscribe(() -> { 
     otherService.doAction() 
    } 

편집 : 쓰레기 수집.

WeakReference를 사용하는 것과 같이 매우 이상한 것을하지 않는 한, 실행 코드 doSomething은 전체 체인이 가비지 수집되지 않도록합니다.

RxJava를 양파와 같이 생각하면, 관찰 가능 (map, doOnNext 등)을 변형 할 때마다 양파와 같은 오래된 관측 가능을 감싸는 새로운 Observable이 생성됩니다.

각 변형에 대해 콜백 (onNext, onCompleted, onError)을 체인의 다음 Subscriber으로 전달하는 새로운 Subscriber이 생성됩니다.

Subscription의 주된 이유는 unsubscribe입니다. 탈퇴를 요청할 수있는 두 가지 이유가 있습니다.

  1. 당신은 뜨겁게 관측 할 수 있습니다. 기본적으로이 관측 가능 값은 영원히 값을 방출합니다. 보기는 30 초마다 시간을내는 관측자 일 수 있습니다. 더 이상 시간 가치에 관심이 없으면 unsubscribe으로 전화 할 수 있습니다.

  2. 오랜 작업을 취소하고 싶습니다. 사용자가 웹 페이지를로드하여 사용자에게 표시한다고 가정 해 보겠습니다. 사용자가 다시 누르면로드를 취소하려는 경우 (결과에 더 이상 관심 없음). 지도 작업에 대한

소스 코드

지도는 단순히 인수로 OperatorMap으로 lift를 호출합니다. 리프트는 Operator을 기반으로 새로운 Observable을 만듭니다. 당분간 무시해도됩니다.

public final <R> Observable<R> map(Func1<? super T, ? extends R> func) { 
    return lift(new OperatorMap<T, R>(func)); 
} 

OperatorMap은 대부분 단지가 주어진 어떤 Subscriber에 호출을 전달하는 새로운 Subscriber을 만듭니다.이 이 subscribe으로 전달되거나 Subscriber이 다른 map 변형으로 생성 될 수 있습니다. 실제로 문제가되지는 않습니다.

public final class OperatorMap<T, R> implements Operator<R, T> { 

    private final Func1<? super T, ? extends R> transformer; 

    public OperatorMap(Func1<? super T, ? extends R> transformer) { 
     this.transformer = transformer; 
    } 

    @Override 
    public Subscriber<? super T> call(final Subscriber<? super R> o) { 
     return new Subscriber<T>(o) { 

      @Override 
      public void onCompleted() { 
       o.onCompleted(); 
      } 

      @Override 
      public void onError(Throwable e) { 
       o.onError(e); 
      } 

      @Override 
      public void onNext(T t) { 
       try { 
        o.onNext(transformer.call(t)); 
       } catch (Throwable e) { 
        Exceptions.throwOrReport(e, this, t); 
       } 
      } 

     }; 
    } 

} 
+1

아 ... 그 쉬운 것 같다하지만 난 혼란 스러워요. 가비지 수집에서 전체 객체 체인을 중지시키는 것은 무엇입니까? – Buttink

+0

간단히 말해서,'doSomething'에있는 실행 코드는 더 자세한 내용에 대한 업데이트 된 답변을 볼 수 있습니다. – cyroxis

+0

전체 오브젝트 체인이 가비지 콜렉션을 가져 오지 못하게하는 것은 보유중인 'Subscription'입니다. (cyroxis가 말했듯이 : "구독을 계속한다면 잊지 않고 있습니다.") 구독이 없으면 데이터에 접근 할 수 없으며 (다른 데이터와 연결되어 있지 않음) 가비지 수집됩니다. –

0

귀하의 CompositeSubscription은 원하는 부모 개체에 저장해야합니다. 그러면 CompositeSubscription의 부모가 CompositeSubscription에 연결됩니다. 부모 개체에 연결할 수 없으면 부모 개체가있는 CompositeSubscription은 모두 가비지 수집됩니다.

또한 CompositeSubscription의 부모가 onStop()과 같은 라이프 사이클 메소드를 사용하는 경우 수동으로 CompositeSubscription의 수신을 거부 할 수 있습니다. 마찬가지로 onStart() 또는 onResume()과 같은 라이프 사이클 메소드를 사용할 수있는 경우 (다시) 구독 할 수 있습니다.

This page 가비지 수집에 대한 자세한 정보를 제공 할 수 있습니다.

1

가입 여부를 알고 싶지 않으면 가입을 잊어 버리십시오. 설계 상 Observable은 onComplete 옵저버의 등록을 취소합니다. 그런 다음 인스턴스가 더 이상 사용되지 않으므로 GC가 어느 시점에서이를 제거합니다.

당신의 코드를 리팩토링 :

service.doSomething().timeout(10, TimeUnit.SECONDS) 
           .subscribe(() -> { 
            otherService.doAction() 
           }, (e) -> { Log.e("error", e) }); 

당신은 여기에 작품을 등록하는 방법에 대한 예를 볼 수 있습니다.

https://github.com/politrons/reactive/blob/master/src/test/java/rx/observables/creating/ObservableSubscription.java

관련 문제