'How to call API again when there is Network or Timeout Error in Android Volley Request

I am using a custom common class named APIHelper for Volley JsonObjectRequest for my all activities. I am handling all type of errors here. And setting positive response through interface and handling in all activities.

APIHelper Class:

private static final String baseurl = BuildConfig.BASE_URL;
private static final String version = "api/v1/";
private ApiService apiService;

public void getResponse(ApiService apiService) {
        this.apiService = apiService;
}

public void callAPI(Context context, String url, int REQUEST, JSONObject parameters) {

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(REQUEST, baseurl + version + url, parameters, response -> {

   apiService.onResponse(response);

}, error -> {

NetworkResponse response = error.networkResponse;
if (response != null && response.statusCode == 401) {
Utility.showToastMessage(context, "Session Expired! Please login to continue", "error");
Intent intent = new Intent(context, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(intent);
}

if (error instanceof NoConnectionError | error instanceof TimeoutError) {
      // I implemented here a Alert Dialog of Network Error or TimeoutError.
      // Now on click on Retry Button in Alert Dialog, I need to call same API again to perform action.
}

if (error instanceof ServerError && response != null) {
try {
String res = new String(response.data, HttpHeaderParser.parseCharset(response.headers, "utf-8"));
JSONObject jsonObject = new JSONObject(res);

} catch (UnsupportedEncodingException | JSONException e) {
       e.printStackTrace();
}
            }
        }) {
            @Override
            public Map<String, String> getHeaders() {
                HashMap<String, String> header = new HashMap<>();
                header.put("Content-Type", "application/json");
                header.put("Authorization", "Bearer " + sessionToken);
                header.put("timezone", TimeZone.getDefault().getID());
                return header;
            }
        };

        RequestQueue queue = Volley.newRequestQueue(context);

        int socketTimeout = 20000;//20 seconds - change to what you want
        jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(socketTimeout, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

        queue.add(jsonObjectRequest);
}

ApiService Interface Class:

public interface ApiService {

void onResponse(JSONObject jsonResponse);
}

My First Activity:

apiHelper.callAPI(this, URL_LOGIN, Request.Method.POST, parameters);
apiHelper.getResponse(jsonResponse -> {

// Doing positive stuff here....
        
});

My Second Activity:

apiHelper.callAPI(this, URL_OTP, Request.Method.POST, parameters);
apiHelper.getResponse(jsonResponse -> {

// Doing positive stuff here....
        
});

I implemented a Alert Dialog in APIHelper Class when I got any Network Error or TimeoutError. There is a Retry button in Alert Dialog.

My question is:

When I click on Retry Button in Alert Dialog, I need to call same API again to perform action. How is this possible. Please help.

Note: I don't want to implement No Network Alert Dialog option in Activities/Fragments/Adapters because I have more than 100 activites/Fragments/Adapters.



Solution 1:[1]

You are creating your alert dialog inside your callAPI method. Then you should be able to make another call to your callAPI method when Retry button is clicked.

Here is a modified version of your callAPI method's error callback. Let me know if this is what you need.

if (error instanceof NoConnectionError | error instanceof TimeoutError) {
            AlertDialog.Builder builder = new 
            AlertDialog.Builder(context);
            builder.setMessage("some network related message");
            builder.setPositiveButton("RETRY", (dialog, which) -> {
                dialog.cancel();
                // Make another call to callAPI with the same parameter
                callAPI(context, url, REQUEST, parameters)
            });
            builder.setNegativeButton("CANCEL", (dialog, which) -> {
                dialog.cancel();
            });
            builder.show();
        }

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 rbd_sqrl