Sequential requests using asynchronous Retrofit methods

Asked

Viewed 52 times

0

Hello. I am developing an application where it is necessary to synchronize the data at certain times. I am using Retrofit to connect to the api and send/receive the data, but each request needs to be made only when the previous request ends. How is it possible to do this?

Interface with the requests:

public interface DownloadService {

@GET("ciclo/current")
Call<JsonObject> getCicloAtual(@Header("Authorization") String token);

@GET("ciclo/last")
Call<JsonObject> getCicloLast(@Header("Authorization") String token);

@GET("imoveis")
Call<JsonObject> getImoveis(@Header("Authorization") String token);

@GET("pessoas")
Call<JsonObject> getPessoas(@Header("Authorization") String token);}

The client:

public class RetrofitClient {
private static String BASE_URL = "http://xxx.xxx.x.x:8000/api/";
private static Retrofit retrofit;

public static Retrofit getInstance(){
    if(retrofit == null) {
        return retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    return retrofit;
}

public static AuthService authService() {return  getInstance().create(AuthService.class);}

public static DownloadService downloadService() {return  getInstance().create(DownloadService.class);}

public static SyncService syncService(){
    return  getInstance().create(SyncService.class);
}}
  • The next request must be made in the method where you receive the result of the previous request.

  • Is there any other way? There are still many requests to be made beyond these 4 code and I didn’t want it to get messy.

1 answer

1

With the Calls of the retrofit there are not many possibilities without being in the method onResponse(Call<T> call, Response<T> response) of Callbackas explained in the comments.

An example would be:

Retrofit instance = getInstance();
instance.getCicloAtual("token")
   .enqueue(new Callback<JsonObject>() {
        @Override
        public void onResponse(Response<JsonObject> response) {
            // Aqui a gente faz a próxima call
            instance.getCicloLast("token")
               .enqueue(new Callback<JsonObject>() {
                  // e por aí fora
               });
        }

        @Override
        public void onFailure(Throwable t) {}
    });

It won’t be the most beautiful code in the world, but it will work.


Another way is to call Calls synchronously. However, everything has to be done on another thread other than the main. For example, we can do:

Retrofit instance = getInstance();
new Thread(() -> {
    JsonObject result = instance.getCicloAtual("token").execute();
    // a próxima linha só corre quando a de cima terminar
    result = instance.getCicloLast("token");
}

This mode has other problems - We have to try to return the result to whoever called those Apis and most likely in the main-thread with the help of a Handler. We have to deal with exceptions and errors. We have to finish the requests manually if for example the application is put in the background.


Another option is to use one CallAdapter that does not use Callbacks. Could be for example RxJava or coroutines. With these call Adapters, although the code is synchronous, it is written as if it were synchronous. So it doesn’t get messy at all, but it probably makes a big difference in the code you have now.

I hope it helps.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.