I'm trying to add restMedia
to restaurantMediaList
in onResponse
within a for loop. However, when the loop is finished, restaurantMediaList
is null. How can I fix this in such a way that it waits for onResponse
to be finished first before proceeding with the next iteration?
public void getImages(List<Restaurant> restaurantList, OnImageReceivedCallback callback){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://example.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
WordpressAPICall wordpressAPICall = retrofit.create(WordpressAPICall.class);
for(int i = 0; i < restaurantList.size(); i++){
String featuredMediaURL = restaurantList.get(i).get_links().getFeaturedMedia().get(0).getHref();
featuredMediaURL.substring(featuredMediaURL.indexOf("v2")+1);
Call<RestaurantMedia> restMediaCall = wordpressAPICall.getImage(featuredMediaURL);
restMediaCall.enqueue(new Callback<RestaurantMedia>() {
@Override
public void onResponse(Call<RestaurantMedia> call, Response<RestaurantMedia> response) {
RestaurantMedia restMedia = response.body();
restaurantMediaList.add(restMedia);
//callback.onRestaurantListReceived(restaurantModels, restMedia);
}
@Override
public void onFailure(Call<RestaurantMedia> call, Throwable t) {
Log.d("Fail to get media", t.toString());
}
});
}
callback.onImageReceived(restaurantMediaList);
}
Keep in mind that there are restaurantList.size()
different threads (each fires a network request) and the only choice you have is to use some lock.
If there is an API that fetches all of the images together please use it and use my 1st code to wait for result.
I also recommend using timeout because if, for some reason, onResponse
AND onFailure
will not be called, your calling thread will sleep forever. Tweak the timeout as you see fit.
Waiting for each thread to finish separately is extremely time consuming so I'd recommend to let them go asynchronous and continue when all of them are done.
I'll show you both options.
Wait for each one to wait separately:
CountDownLatch countDownLatch = new CountDownLatch(1);
restMediaCall.enqueue(new Callback<RestaurantMedia>() {
@Override
public void onResponse(Call<RestaurantMedia> call, Response<RestaurantMedia> response) {
// Do your thing
countDownLatch.countDown();
}
@Override
public void onFailure(Call<RestaurantMedia> call, Throwable t) {
// Do your thing
countDownLatch.countDown();
}
});
countDownLatch.await(1L, TimeUnit.SECONDS); // join thread with timeout of second
Waiting for all threads together:
public void getImages(List<Restaurant> restaurantList, OnImageReceivedCallback callback){
// Do your thing
CountDownLatch countDownLatch = new CountDownLatch(restaurantList.size());
for(int i = 0; i < restaurantList.size(); i++){
// Do your thing
restMediaCall.enqueue(new Callback<RestaurantMedia>() {
@Override
public void onResponse(Call<RestaurantMedia> call, Response<RestaurantMedia> response) {
// Do your thing
countDownLatch.countDown();
}
@Override
public void onFailure(Call<RestaurantMedia> call, Throwable t) {
// Do your thing
countDownLatch.countDown();
}
});
}
countDownLatch.await(1L * restaurantList.size(), TimeUnit.SECONDS); // join thread with timeout of second for each item
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.