Camilo Camargo
Camilo Camargo

Reputation: 61

Android volley - get callback when all request finished

I appreciate any help you can give me. I have the following problem:

I have an application that uses SyncAdapter to synchronize periodically and manually the local database with the server data. But I need that when the user is just going to log in to the application, a manual synchronization is performed, while a load dialog is displayed. After the synchronization completes, the dialog should be hidden, and the main activity should be displayed. What dou you recommend?

I'm using volley to handle HTTP requests. I'm a bit confused, since the requests always run asynchronously, and so it is difficult to know when all the requests finish to hide the dialog.

The code is as follows:

VolleySingleton.getInstance(getContext()).addToRequestQueue(
        new JsonObjectRequest(
            Request.Method.GET,
            Constants.GET_URL,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    // This method sync the data
                    updateLocalData(response, syncResult);
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    getContext().sendBroadcast(new Intent(Constants.SYNC_CORRUPTED_BY_SERVER));
                    Log.d(TAG, "Sync (makeLocalSync), Exception => " +
                            error.getLocalizedMessage());
                }
            }
        )
    );

Sorry for my English level...

Thanks!

Upvotes: 2

Views: 7911

Answers (4)

Aslam a
Aslam a

Reputation: 759

addRequestFinishedListener is deprecated now, use addRequestEventListener

  requestQueue.addRequestEventListener((request, event) -> {
        if(event == RequestQueue.RequestEvent.REQUEST_FINISHED ){
            if(totalRequests.decrementAndGet() == 0){
                 Log.d("tag", "finished");
            };
        }
    });

Upvotes: 0

Dyno Cris
Dyno Cris

Reputation: 2414

I use this code:

queue.addRequestFinishedListener(request -> {
        countRequests++;
        if (countRequests == 2) {
            Log.d("tag", "finished");
        }
    });

Upvotes: 0

Camilo Camargo
Camilo Camargo

Reputation: 61

I have solved my problem as follows:

In each of the "n" Volley requests, within their methods Response.Listener and Respones.ErrorListener I use a counter and a flag that allows me to handle a broadcast, as follows:

If the value of the counter is equal to the number of requests then all the requests have been completed, then, with the flag I check if any request presented a problem or not.

The code is as follows:

Request # n1:

    // Counter and flag to handle requests
    private static int iCountRequest;
    private static boolean bAnyErrors;
    // Before initiating all the requests, the variables must be restarted
    iCountRequest = 0;
    bAnyErrors = false;
    // Request # n1:
    VolleySingleton.getInstance(getContext()).addToRequestQueue(
            new JsonObjectRequest(
                    Request.Method.GET,
                    Constants.REQUEST_N1_URL,
                    new Response.Listener<JSONObject>() {
                        @Override
                        public void onResponse(JSONObject response) {
                            iCountRequest++;
                            // Response code..
                            sendBroadcastToActivity();
                        }
                    },
                    new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            iCountRequest++;
                            bAnyErrors = true;
                            sendBroadcastToActivity();
                        }
                    }
            )
    );

sendBroadCast Function:

if (iCountRequest == Constants.NUMBER_OF_REQUEST) {
        if (!bAnyErrors) {
            getContext().sendBroadcast(new Intent(Constants
                    .SYNC_IN_ORDER_FINISHED));
        } else {
            getContext().sendBroadcast(new Intent(Constants
                    .SYNC_IN_ORDER_FINISHED_WITH_ERRORS));
        }
    }

VolleySingleton:

public final class VolleySingleton {

    private static VolleySingleton oSingleton;
    private RequestQueue oRQ;
    private static Context oContext;

    private VolleySingleton(Context context) {
        VolleySingleton.oContext = context;
        oRQ = getRequestQueue();
    }

    public static synchronized VolleySingleton getInstance(Context context) {
        if (oSingleton == null) {
            oSingleton = new VolleySingleton(context.getApplicationContext());
        }
        return oSingleton;
    }

    private RequestQueue getRequestQueue() {
        if (oRQ == null) {
            oRQ = Volley.newRequestQueue(oContext.getApplicationContext());
        }
        return oRQ;
    }

    public <T> void addToRequestQueue(Request<T> req) {
        getRequestQueue().add(req);
    }

}

I hope it works for you. Thanks @FerDensetsu

Upvotes: -1

FerDensetsu
FerDensetsu

Reputation: 746

Unfortunately, Volley's RequestQueue doesn't provide any interface nor callback to let you know when all pending requests finished. A workaround I found to notify when all requests are done is to update an int and a boolean class members for every request's response or fail. It is important that your requests have access to these members and also the number corresponds to the updated value, so when this value descends to 0, you'll know all requests are done.

private int numberOfRequestsToMake = NUMBER;
private boolean hasRequestFailed = false; 

Then, when creating requests:

JsonObjectRequest req = new JsonObjectRequest(url, null,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    Log.d(TAG, "successful request to " + url);
                    numberOfRequestsToMake--;

                    if(numberOfRequestsToMake == 0) {
                        if(!hasRequestFailed) {
                            //All requests finished correctly
                        } else {
                            //At least one request failed
                        }
                    }
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.e(TAG, "unsuccessful request to " + url);
                    numberOfRequestsToMake--;
                    hasRequestFailed = true;

                    if(numberOfRequestsToMake == 0) {
                        //The last request failed
                    }
                }
            }
    );

    MyVolleySingleton.getInstance().addToRequestQueue(req);

Upvotes: 6

Related Questions