2017-05-15 1 views
0

나는 내 애플 리케이션을 android repository by Fernando Cejas에 짓고 있는데, dispose을 호출 한 후 observable에 가입하는 데 문제가있다.처분 후 observable에 가입 ​​

내가 대시 보드에 왔을 때, 나는 방법은 단순히 내가 만들 내 소켓 구현에서이 return messageRepository.subscribeOnUserMessages(params);

같은 저장소를 호출 자식 클래스 SubscribeOnUserMessages에서 UseCase 클래스

public void execute(DisposableObserver<T> observer, Params params) { 
    Preconditions.checkNotNull(observer); 
    final Observable<T> observable = this.buildUseCaseObservable(params) 
      .subscribeOn(Schedulers.from(threadExecutor)) 
      .observeOn(postExecutionThread.getScheduler()); 
    addDisposable(observable.subscribeWith(observer)); 
} 

에 인 방법 subscribeOnUserMessages.execute(new Subscriber(), new Params(token)) 전화 like

return Observable.create(emitter -> { 

     if (!isThereInternetConnection()) { 
      Timber.w("Network connection exception"); 
      emitter.onError(new NetworkConnectionException()); 
      return; 
     } 

     /* 
     * Open socket if not opened 
     */ 
     openSocket(params.getToken()); 



     String channelName = CHANNEL_PRIVATE_USER + params.getAuthenticated().getUuid(); 

     if (subscribedChannels.contains(channelName)) { 
      Timber.d("Channel %s is already subscribed", channelName); 
      return; 
     } 


     JSONObject auth; 

     try { 
      auth = createAuthJson(CHANNEL, channelName, params.getToken()); 
     } catch (JSONException e) { 
      Timber.e("Couldn't create auth json"); 
      emitter.onError(e); 
      return; 
     } 

     mSocket.emit(SUBSCRIBE, auth); 
     Timber.d("Emitted subscribe with channel: %s ", CHANNEL_PRIVATE_USER + params.getAuthenticated().getUuid()); 
     subscribedChannels.add(CHANNEL_PRIVATE_USER + params.getAuthenticated().getUuid()); 
     Timber.d("Subscribing on event: %s\n with user: %s", EVENT_USER_NEW_MESSAGE, params.getAuthenticated().getUuid()); 

     if (mSocket.hasListeners(EVENT_USER_NEW_MESSAGE)) { 
      Timber.v("Socket already has listener on event: %s", EVENT_USER_NEW_MESSAGE); 
      return; 
     } 


     mSocket.on(EVENT_USER_NEW_MESSAGE, args -> { 
      if (args[1] == null) { 
       emitter.onError(new EmptyResponseException()); 
      } 

      Timber.d("Event - %s %s", EVENT_USER_NEW_MESSAGE, args[1].toString()); 

      try { 
       MessageEntity messageEntity = messageEntityJsonMapper.transform(args[1]); 
       emitter.onNext(messageEntity); 
      } catch (JSONException e) { 
       Timber.e(e, "Could not parse message json"); 
       emitter.onError(e); 
      } 
     }); 

    }); 

증상 a 내가 처음으로 모든 것을 구독 할 때 프리젠 테이션 레이어로 진행됩니다. 내가 두 번째 화면으로 이동 한 후 처분 할 때 나는 단지 소켓 구현으로 오는 로그를 보지만 돌아 가지 않습니다.

내 질문은 : 동일한 관찰 가능에 다시 구독 할 수있는 방법이 있습니까? 나는 이미 싱글 톤의 유스 케이스에 관측 가능 내용을 저장하고 그 관측 가능 부분에 가입하려고 시도했지만 도움이되지 않았습니다.

+0

은 관찰 가능 객체에'.subscribe()'를 다시 호출합니다. –

+0

동일한 관찰 대상에 다시 가입 하시겠습니까? Observable 또는 Observable입니까? 다시 구독하는 경우 어떤 결과를보고 싶습니까? –

+0

'SocketImpl'은 소켓에서 메시지를 가져 오는 책임을지는 싱글 톤 객체입니다. –

답변

0

소켓 구현을 보완하는 추가 정보 및 세부 정보가 없으면 문제를 정확하게 파악하는 것이 어렵지만 게시 한 코드에서 로직을 처리 할 필요가 없으므로 dispose()Observable 올바른 라이프 사이클 이벤트가 발생하면 소켓이 실제로 열린 상태로 유지되고 연결이 끊어지지 않거나 제대로 닫히지 않을 수 있습니다.
이미 열려있는 소켓을 다시 열려고 시도 할 때 문제가 될 수있는 내부 소켓 impl에 따라 달라 지므로 두 번째 시간에 소켓을 열고 연결하는 데 문제가 발생할 수 있습니다.
은 일반적인 가이드 라인으로

(다시 소켓 IMPL에 따라, openSocket가 이미 열려하지 않을 경우 그 의견에 볼 수 있지만 여전히 다른 곳에서 여러 번 소켓에 대한 몇 가지 방법을 전화 또는 청취자의 설정에 문제가있을 수 있습니다) 더 이상 필요하지 않을 때 소켓 리소스를 올바르게 처리하기 위해 emitter.setCancellable()/emitter.setDisposable()을 사용하여 처리 로직을 추가해야합니다. 다시 구독을 적용하면 (동일한 객체인지 여부에 관계없이) 소켓을 다시 열어 구독 로직을 다시 호출합니다 그것을 들어라.

다른 화면으로 이동할 때 소켓을 열린 상태로 유지하고 싶다면 분명하지 않습니다 (좋은 사례라고 생각하지 않습니다.이 리소스를 열어두고 다시 돌아올 수 없기 때문입니다). @Phoenix Wang이 언급했듯이 게시 할 종류 연산자를 사용하여 Observable을 멀티 캐스팅 할 수 있으므로 모든 새 Subscriber이 소켓을 다시 열려고 시도하지는 않지만 (구독 로직을 호출하는) 이미 열려있는 소켓에서 실행중인 메시지에 대해 알리십시오.

+0

나는'emitter.setCancellable()'과'emitter.setDisposable()'을 시도했지만,이 메소드들에는 속하지 않을 것이다. 어쩌면 나는 에미 터를 올바르게 초기화하지 못할 수도있다. –

+0

도'observable.doOnDispose()'를 시도했지만 행운은 없습니다. –

+0

Observable을 처분 할 때 실행되지 않았습니까? 추가 연산자가 적용 되었습니까? – yosriz