2016-02-10 9 views
5

Próbuję użyć retrofitu + rxjava, aby zagnieżdżać wywołania api. Zasadniczo muszę zbudować listę obiektów biblioteki. Każdy obiekt biblioteki ma listę autorów, a każdy obiekt autora ma listę książek. Tak jest skonstruowany mój json.Połączenia Chwilowe Retrofit za pomocą RxJava i zwracanie głównego obiektu

json biblioteka -

{ 
title: "Library", 
items: [ 
     { 
     title: "Library1" 
     image: "http://example.com/image/101/image_lib1.png" 
     url: "http://example.com/api/1" 
     }, 
     { 
     title:"Library2" 
     image: "http://example.com/image/101/image_lib2.png" 
     url: "http://example.com/api/2" 
     }, 
     { 
     title:"Library3" 
     image: "http://example.com/image/101/image_lib3.png" 
     url: "http://example.com/api/3" 
     } 
    ] 
} 

i autorów json-

{ 
title: "Authors", 
items: [ 
     { 
     title: "J.K Rowling" 
     image: "http://example.com/image/101/image_author1.png" 
     url: "http://example.com/api/101" 
     }, 
     { 
     title:"Mark Twain" 
     image: "http://example.com/image/101/image_author2.png" 
     url: "http://example.com/api/201" 
     }, 
     { 
     title:"Charles Dickens" 
     image: "http://example.com/image/101/image_author3.png" 
     url: "http://example.com/api/301" 
     } 
    ] 
} 

i książki json-

{ 
description: Books, 
imageurl: "http://example.com/image/101/image_101.png", 
items: [ 
    { 
    id: 101, 
    title: "Oliver Twist ", 
    description: "some description" 
    }, 
    { 
    id: 1011, 
    title: "Hard times", 
    description: "some more description." 
    } 
} 
] 
} 

Mój interfejs API jest podane poniżej.

@GET("/api/") 
    Observable<LibraryResponse> getLibraryList(); 

    @GET("/api/{feedId}") 
    Observable<AuthorResponse> getAuthorList(@Path("feedId") String feedId); 

    @GET("/api/{feedId}") 
    Observable<BooksResponsee> getBooksList(@Path("feedId") String feedId); 




Observable<List<Library>> observable = myRestInterface 
    .getLibraryList() 
    .map(a -> a.getItems()) 
    .flatMapIterable(b -> b)     
    .flatMap(h -> myRestInterface                 
        .getAuthorList(h.getUrl().substring(h.getUrl().lastIndexOf("/") + 1))          
        .map(x -> x.getItems()) 
        .flatMapIterable(l -> l) 
        .flatMap(e -> myRestInterface 
           .getBooksList(e.getUrl().substring(e.getUrl().lastIndexOf("/") + 1)) 
           .map(d -> d.getItems()) 
           .flatMapIterable(c -> c))) 

    .collect(// ? into list of main object) 
    .doOnNext(mainObjectList -> new ViewupdateMethod(mainObjectList)); 
    .subscribe(...); 

Próbuję skonstruować jeden obiekt Librarylist, którego mogę użyć do aktualizacji mojego interfejsu użytkownika. Trochę utknąłem tutaj. Po wykonaniu wielu połączeń, w jaki sposób zapisać wyniki i zebrać wszystko do listy obiektów biblioteki?

+0

Może powinieneś wypróbować '.toList()'? – Alexander

+0

Po co pytać autorów i ich książki, jeśli interesują Cię tylko biblioteki? Jeśli potrzebujesz tutaj czegoś takiego jak SQL, musisz zbudować inną klasę, LibraryWithAuthorsWithBooks –

+0

@KirillGamazkov, Moja biblioteka POJO zawiera listę , a autor POJO zawiera LIs of Books. Więc muszę wypełnić wszystko i uzyskać obiekt biblioteki – Sammys

Odpowiedz

3
Observable<List<Library>> observable = myRestInterface 
      .getLibraryList() 
      .flatMapIterable(response -> response.getItems()) 
      .doOnNext(library -> myRestInterface 
        .getAuthorList(library.getUrl().substring(library.getUrl().lastIndexOf("/") + 1)) 
        .flatMapIterable(response -> response.getItems()) 
        .doOnNext(author -> library.getAuthors().add(author)) 
        .doOnNext(
          author -> myRestInterface 
            .getBooksList(author.getUrl().substring(author.getUrl().lastIndexOf("/") + 1)) 
            .flatMapIterable(response -> response.getItems()) 
            .doOnNext(book -> author.getBooks().add(book)) 
            .subscribe() 
        ) 
        .subscribe() 
      ) 

      .doOnNext(mainObjectList -> new ViewupdateMethod(mainObjectList)) 
      .subscribe(); 

Notatka .subscribe() połączenia. Służą do rozpoczęcia realizacji całego łańcucha. RxObservable nie robi nic, dopóki nie pojawi się subskrybent.

+0

Jak ponowić subskrypcję, jeśli status się nie powiódł? na przykład muszę sprawdzić status mojej prośby z serwera i jeśli mam "status oczekiwania", muszę ponownie wysłać żądanie, aż otrzymam "status kontynuacji", a następnie kontynuować proces subskrypcji. – neilQ5

+0

Nie jestem pewien, czy podążam za tobą. RxJava oferuje wiele metod radzenia sobie z ponowieniem, zaczynając od Observable # retry i kilku innych. Jeśli żadna z nich nie wydaje się pasować do twoich potrzeb, możesz uwzględnić logikę ponawiania w swojej "myRestInterface.getLibraryList()" lub wyodrębnić ją do fragmentu kodu wielokrotnego użytku i używać go razem z Observable # compose –

+0

tl; dr - po prostu możesz po prostu put .retry() tuż przed .subscribe(), robi to dla Ciebie? –