2017-06-08 16 views
5

tworzę zagnieżdżone żądań, jak następuje (niektóre obsługę błędów pominięta):doposażenia JavaRx2 gwint przerywany

return Single.create((SingleOnSubscribe<String>) emitter -> getPages() 
    .subscribe(pages -> getPageData(emitter, pages), emitter::onError)) 
    .compose(applySchedulers()); 

    // ... 

private void getPageData(SingleEmitter<String> emitter, List<Page> pages) { 
    service.getPage(pages.get(0).id) 
      .subscribe(emitter::onSuccess, e -> { 
       pages.remove(0); 
       getPageData(emitter, pages); 
      }); 
} 

że użyte do iteracyjnego rozwiązania, które uprzednio wytworzonej ten sam rezultat. Lista stron jest posortowana w kolejności i powinna zostać przetworzona jako taka. Ta część kodu działa, jeśli połączenie jest dobre, jednak jeśli mam złe połączenie, otrzymuję java.io.InterruptedIOException: thread interrupted. Jaki byłby dobry sposób rozwiązania tego problemu?

EDIT:

StackTrace:

W/System.err: java.io.InterruptedIOException: thread interrupted 
W/System.err:  at okio.Timeout.throwIfReached(Timeout.java:145) 
W/System.err:  at okio.Okio$2.read(Okio.java:136) 
W/System.err:  at okio.AsyncTimeout$2.read(AsyncTimeout.java:237) 
W/System.err:  at okio.RealBufferedSource.read(RealBufferedSource.java:46) 
W/System.err:  at okhttp3.internal.http1.Http1Codec$ChunkedSource.read(Http1Codec.java:429) 
W/System.err:  at okio.RealBufferedSource.read(RealBufferedSource.java:46) 
W/System.err:  at okio.RealBufferedSource.exhausted(RealBufferedSource.java:56) 
W/System.err:  at okio.InflaterSource.refill(InflaterSource.java:101) 
W/System.err:  at okio.InflaterSource.read(InflaterSource.java:62) 
W/System.err:  at okio.GzipSource.read(GzipSource.java:80) 
W/System.err:  at okio.RealBufferedSource.read(RealBufferedSource.java:46) 
W/System.err:  at okio.ForwardingSource.read(ForwardingSource.java:35) 
W/System.err:  at retrofit2.OkHttpCall$ExceptionCatchingRequestBody$1.read(OkHttpCall.java:291) 
W/System.err:  at okio.Buffer.writeAll(Buffer.java:1005) 
W/System.err:  at okio.RealBufferedSource.readString(RealBufferedSource.java:190) 
W/System.err:  at okhttp3.ResponseBody.string(ResponseBody.java:175) 

EDIT 2:

Funkcja getPages:

private Single<List<Page>> getPage() { 
     return Observable.merge(service.getPage("mn").toObservable(), 
       service.getPage("fc",).toObservable(), 
       service.getPage("sh").toObservable()) 
       .map(PageParser::parseActive) 
       .flatMap(Observable::fromIterable) 
       .sorted((f1, f2) -> f2.wage - f1.wage) 
       .toList(); 
} 
+0

To samo tutaj. Czy próbowałeś użyć rxFragment? compile 'com.trello.rxlifecycle2: rxlifecycle-navi: 2.0.1' skompiluj "com.trello.rxlifecycle2: rxlifecycle: 2.0.1 ' skompiluj" com.trello.rxlifecycle2: rxlifecycle-components: 2.0.1' –

+0

I "już korzystam z komponentów architektury, nie jest to spowodowane wstrzymaniem aktywności – tofiffe

+0

proszę dodać ślad stosu. czym dokładnie jest 'getPages()'? dlaczego zagnieżdżasz się w "Observables", istnieją lepsze, bardziej przejrzyste sposoby, czego się spodziewasz po słabych połączeniach? – yosriz

Odpowiedz

0

Może Znalazłem rozwiązanie tego problemu:

private void getPageData(SingleEmitter<String> emitter, List<Page> pages) { 
    try { 
    service.getPage(pages.get(0).id) 
      .subscribe(emitter::onSuccess, e -> { 
       pages.remove(0); 
       getPageData(emitter, pages); 
      }); 
    } catch (InterruptedIOException e) { 
     Log.d(TAG, e.getLocalizedMessage(), e); 
    } 
} 

Należy użyć rxFragment składnik przerwać rxJava2 wątek gdy tys fragment lub aktywność zostaje zatrzymana przez użytkownika:

observable.compose(RxLifecycle.<NetworkResult, FragmentEvent>bindUntilEvent(lifecycle(), FragmentEvent.STOP)); 

jednak wyjątek ThreadInterrupted będzie występować, ponieważ trzeba obsłużyć sobie wyjątek Retrofit2 i po prostu zignorować. Robienie tego w ten sposób działa bardzo dobrze dla mnie!

Powiązane problemy