5 votes

Retrofit JavaRx2 thread interrompu

Je crée des requêtes imbriquées comme suit (gestion des erreurs omise):

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

    // ...

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

J'avais précédemment une solution itérative, qui produisait le même résultat. La liste de pages est triée et doit être traitée comme telle. Cette partie du code fonctionne si la connexion est bonne, cependant si je me trouve sur une mauvaise connexion, j'obtiens java.io.InterruptedIOException: thread interrupted. Quelle serait une bonne façon de résoudre cela?

MODIFIER:

la trace de la pile:

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)

MODIFIER 2:

La fonction getPages:

private Single> 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();
}

0voto

Dany Poplawec Points 2203

Peut-être ai-je trouvé une solution pour cela :

private void getPageData(SingleEmitter emitter, List 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);
   }
}

Vous devriez utiliser le composant rxFragment pour interrompre le thread rxJava2 lorsque le fragment ou l'activité est arrêté par l'utilisateur:

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

Mais l'exception ThreadInterrupted se produira car vous devriez gérer vous-même l'exception pour Retrofit2 et tout simplement l'ignorer. Faire de cette façon fonctionne très bien pour moi!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X