Skip to content

Instantly share code, notes, and snippets.

@Macrow
Created May 24, 2017 17:00
Show Gist options
  • Save Macrow/99e2be7208dd42d76c0be8556dc785b0 to your computer and use it in GitHub Desktop.
Save Macrow/99e2be7208dd42d76c0be8556dc785b0 to your computer and use it in GitHub Desktop.
Android, RxJava and Retrofit: Wait for multiple network calls to finish
[url]https://newfivefour.com/android-rxjava-wait-for-network-calls-finish.html[/url]
Android, RxJava and Retrofit: Wait for multiple network calls to finish
Say you have multiple network calls you need to make–cals to get Github user information and Github user events for example.
And you want to wait for each to return before updating the UI. RxJava can help you here.
Let’s first define our Retrofit object to access Github’s API, then setup two observables for the two network requests above:
```java
Retrofit repo = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
Observable<JsonObject> userObservable = repo
.create(GitHubUser.class)
.getUser(loginName)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread());
Observable<JsonArray> eventsObservable = repo
.create(GitHubEvents.class)
.listEvents(loginName)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread());
The Retrofit interfaces are simple enough:
public interface GitHubUser {
@GET("users/{user}")
Observable<JsonObject> getUser(@Path("user") String user);
}
public interface GitHubEvents {
@GET("users/{user}/events")
Observable<JsonArray> listEvents(@Path("user") String user);
}
```
Lately we use RxJava’s zip method to combine our two Observables and wait for them to complete before creating a new Observable.
```java
Observable<UserAndEvents> combined = Observable.zip(userObservable, eventsObservable, new Func2<JsonObject, JsonArray, UserAndEvents>() {
@Override
public UserAndEvents call(JsonObject jsonObject, JsonArray jsonElements) {
return new UserAndEvents(jsonObject, jsonElements);
}
});
```
What’s the UserAndEvents? It’s just a simple POJO to combine the two objects:
```java
public class UserAndEvents {
public UserAndEvents(JsonObject user, JsonArray events) {
this.events = events;
this.user = user;
}
public JsonArray events;
public JsonObject user;
}
```
Finally let’s call the subscribe method on our new combined Observable:
```java
combined.subscribe(new Subscriber<UserAndEvents>() {
...
@Override
public void onNext(UserAndEvents o) {
// You can access the results of the
// two observabes via the POJO now
}
});
````
No more waiting in threads etc for network calls to finish. RxJava has done all that for you in zip().
@Macrow
Copy link
Author

Macrow commented May 24, 2017

https://newfivefour.com/android-rxjava-wait-for-network-calls-finish.html

Android, RxJava and Retrofit: Wait for multiple network calls to finish
Say you have multiple network calls you need to make–cals to get Github user information and Github user events for example.

And you want to wait for each to return before updating the UI. RxJava can help you here.

Let’s first define our Retrofit object to access Github’s API, then setup two observables for the two network requests above:

Retrofit repo = new Retrofit.Builder()
        .baseUrl("https://api.github.com")
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .build();

Observable<JsonObject> userObservable = repo
        .create(GitHubUser.class)
        .getUser(loginName)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread());

Observable<JsonArray> eventsObservable = repo
        .create(GitHubEvents.class)
        .listEvents(loginName)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread());
The Retrofit interfaces are simple enough:

public interface GitHubUser {
  @GET("users/{user}")
  Observable<JsonObject> getUser(@Path("user") String user);
}

public interface GitHubEvents {
  @GET("users/{user}/events")
  Observable<JsonArray> listEvents(@Path("user") String user);
}

Lately we use RxJava’s zip method to combine our two Observables and wait for them to complete before creating a new Observable.

Observable<UserAndEvents> combined = Observable.zip(userObservable, eventsObservable, new Func2<JsonObject, JsonArray, UserAndEvents>() {
  @Override
  public UserAndEvents call(JsonObject jsonObject, JsonArray jsonElements) {
    return new UserAndEvents(jsonObject, jsonElements);
  }
});

What’s the UserAndEvents? It’s just a simple POJO to combine the two objects:

public class UserAndEvents {
  public UserAndEvents(JsonObject user, JsonArray events) {
    this.events = events;
    this.user = user;
  }

  public JsonArray events;
  public JsonObject user;
}

Finally let’s call the subscribe method on our new combined Observable:

combined.subscribe(new Subscriber<UserAndEvents>() {
          ...
          @Override
          public void onNext(UserAndEvents o) {
            // You can access the results of the 
            // two observabes via the POJO now
          }
        });

No more waiting in threads etc for network calls to finish. RxJava has done all that for you in zip().

@denizbas92
Copy link

Let's say, if an error occurred on userObservable, how can I continue the next one ? As I understand, If an error occurred on userObservable, the operation is terminated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment