'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!



Solution 1:[1]

I use this code:

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

Solution 2:[2]

addRequestFinishedListener is deprecated now, use addRequestEventListener

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

Solution 3:[3]

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Dyno Cris
Solution 2 Aslam anwer
Solution 3 Camilo Camargo