Gaurav Dureja
Gaurav Dureja

Reputation: 190

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.

Upvotes: 7

Views: 420

Answers (1)

rbd_sqrl
rbd_sqrl

Reputation: 420

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();
        }

Upvotes: 3

Related Questions