2017-10-17 13 views
0

Je construis une activité dans laquelle je charge des listes d'objets à partir d'une API. J'ai besoin de faire plusieurs demandes avec retrofit qui renvoie des objets différents. Je peux faire les demandes mais je ne sais pas comment je peux vérifier quand ils ont fini.Android Retrofit 2 attendre sur plusieurs demandes

Le code suivant est ce que j'ai.

ApiRepository

public interface ApiRepository { 
    @GET("/api/troopmarker.json") 
    Call<List<TroopMarker>> getTroopMarkers(); 

    @GET("/api/troop.json") 
    Call<List<Troop>> getTroops(); 

    @GET("/api/treasure.json") 
    Call<List<TroopMarker>> getTreasures(); 
} 

RepositoryService

public interface RepositoryService 
{ 
    void loadTroops(final TroopCallback callback); 
    void loadTroopMarkers(final TroopMarkerCallback callback); 
    //void loadTreasures(final TreasureCallback callback); 
} 

RepositoryServiceImpl

public class RepositoryServiceImpl implements RepositoryService { 
    private String url; 
    private Activity context; 

    public RepositoryServiceImpl(String url, Activity context) { 
     this.url = url; 
     this.context = context; 
    } 

    public void loadTroops(final TroopCallback callback) { 
     Retrofit retrofit = new Retrofit.Builder() 
       .baseUrl(url) 
       .addConverterFactory(GsonConverterFactory.create()) 
       .build(); 

     ApiRepository repository = retrofit.create(ApiRepository.class); 

     repository.getTroops().enqueue(new Callback<List<Troop>>() { 
      public List<Troop> troops; 

      @Override 
      public void onResponse(Call<List<Troop>> call, Response<List<Troop>> response) { 
       if(response.isSuccessful()) { 
        Log.d("RETROFIT", "RESPONSE " + response.body().size()); 
        callback.onSuccess(response.body()); 
       } 
      } 

      @Override 
      public void onFailure(Call<List<Troop>> call, Throwable t) { 
       CharSequence text = "Error loading troops."; 
       int duration = Toast.LENGTH_LONG; 

       Toast toast = Toast.makeText(context, text, duration); 
       toast.show(); 
       callback.onSuccess(null); 
      } 
     }); 
    } 

    public void loadTroopMarkers(final TroopMarkerCallback callback) { 
     Retrofit retrofit = new Retrofit.Builder() 
       .baseUrl(url) 
       .addConverterFactory(GsonConverterFactory.create()) 
       .build(); 

     ApiRepository repository = retrofit.create(ApiRepository.class); 

     repository.getTroopMarkers().enqueue(new Callback<List<TroopMarker>>() { 
      @Override 
      public void onResponse(Call<List<TroopMarker>> call, Response<List<TroopMarker>> response) { 
       if(response.isSuccessful()) { 
        Log.d("RETROFIT", "RESPONSE " + response.body().size()); 
        callback.onSuccess(response.body()); 
       } 
      } 

      @Override 
      public void onFailure(Call<List<TroopMarker>> call, Throwable t) { 
       CharSequence text = "Error loading troops."; 
       int duration = Toast.LENGTH_LONG; 
       Toast toast = Toast.makeText(context, text, duration); 
       toast.show(); 
       callback.onSuccess(null); 
      } 
     }); 
    } 

    public void loadTreasures() { 

    } 
} 

LoadActivity

public class LoadActivity extends AppCompatActivity 
{ 
    //TODO LOAD TROOPS AND TROOPMARKERS 
    //Load troops, troopmarkers, treasures and put on map 
    public List<Troop> troops; 

    @Override 
    protected void onCreate(@Nullable Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_loading); 

     //Start RepositoryService 
     final RepositoryService repositoryService = new RepositoryServiceImpl("http://internco.eu", this); 

     //Load troops 
     repositoryService.loadTroops(new TroopCallback() { 
      @Override 
      public void onSuccess(List<Troop> troops) { 
       Log.d("RETROFIT", "SUCCESFULLY LOADED TROOPS SIZE: " + troops.size()); 
      } 
     }); 

     //Load troopMarkers 
     repositoryService.loadTroopMarkers(new TroopMarkerCallback() { 
      public List<TroopMarker> troopMarkers; 

      @Override 
      public void onSuccess(List<TroopMarker> troopMarkers) { 
       Log.d("RETROFIT", "SUCCESFULLY LOADED TROOPMARKERS SIZE: " + troopMarkers.size()); 
      } 
     }); 

     //Should now here when I'm done with my requests. 
     Log.d("RETROFIT", "DONE"); 
    } 
} 

Quelqu'un peut-il me faire remarquer à ce sujet? Je pense que je dois utiliser la bibliothèque RxJava mais je ne peux pas comprendre cela.

Votre aide est grandement appréciée.

+0

Votre onSuccess indique que la requête est terminée. L'appel de l'API est une tâche asynchrone. –

Répondre

1

1 façon hacky de le faire serait de garder 2 variables drapeau loadTroopsflag & loadTroopMarkersflag .Ensuite dans les onSuccess callbacks de chaque vérifier si les deux sont vraies et si elles sont alors vos deux demandes sont complètes. Il pourrait y avoir des cas limites dans la mise en œuvre d'une solution de contournement comme celle-ci, mais cela devrait généralement fonctionner. Si vos demandes dépendent les uns des autres alors que vous devrez utiliser imbriquée appelé c.-à-

repositoryService.loadTroops(new TroopCallback() { 
     @Override 
     public void onSuccess(List<Troop> troops) { 
      Log.d("RETROFIT", "SUCCESFULLY LOADED TROOPS SIZE: " + troops.size()); 

      repositoryService.loadTroopMarkers(new TroopMarkerCallback() { 
      public List<TroopMarker> troopMarkers; 

      @Override 
      public void onSuccess(List<TroopMarker> troopMarkers) { 
       Log.d("RETROFIT", "SUCCESFULLY LOADED TROOPMARKERS SIZE: " + troopMarkers.size()); 
      } 
     }); 
     } 
    }); 

Quelque chose comme ça, donc si vous avez plus de dépendances alors votre augmentation de callbacks imbriquées, ce qui est l'endroit où Rxjava viendrait et Résolvez-le en quelques lignes de code.Je ne pense pas que vous ayez besoin de sauter dans Rx pour l'instant car c'est un problème relativement petit et vous obtenez un espace supplémentaire qui augmenterait la taille de l'application ainsi que le temps de développement .

Notez également la partie où vous mentionnez

//Should now here when I'm done with my requests. 
    Log.d("RETROFIT", "DONE"); 

ne signifie pas que les demandes sont faites, cela signifie simplement qu'ils sont mis en attente et en progress.These sont asynchrones et la demande se termine lorsque la fonction de rappel complète .

+1

J'ai utilisé votre hack et ça a marché. :) Ce n'est probablement pas la meilleure et la plus propre façon de le faire, mais cela a fait l'affaire et je n'ai pas besoin de faire autre chose, alors ça me va. Jude Merci pour l'aide-mec! –