Reputation: 289
I am building an activity in which I'm loading lists of objects from an api. I need to make multiple requests with retrofit which returns different objects. I can make the requests but I don't know how I can check when they're done.
The following code is what I have.
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");
}
}
Can someone point me out on this? I think that I have to use the RxJava library but I can't figure this out.
Your help is much appreciated.
Upvotes: 2
Views: 3771
Reputation: 7517
1 hacky way of doing it would be to keep 2 flag variables loadTroopsflag & loadTroopMarkersflag.Then in the onSuccess callbacks of each check whether both are true and if they are then both your requests are complete. There might be edge cases in implementing a workaround like this but it should generally work. In case your requests depend on each other then as you will need to use nested called ie,
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());
}
});
}
});
Something like that,so in case you have more dependencies then your nested callbacks increase which is where Rxjava would come in and solve it in a few lines of code.I don't think you need to jump into Rx just yet as this is a relatively small problem and you Rx java brings in extra space that would increase the size of the app as well as development time.
Also note the part where you mention
//Should now here when I'm done with my requests.
Log.d("RETROFIT", "DONE");
does not imply that the requests are done,it simply means that they are queued up and in progress.These are asynchronous request and will complete when the callback completes.
Upvotes: 2