Обобщенная обработка ошибок волейбола

В моем приложении, я думал о лучшем способе реализации 5xx ответов с сервера.
Первый подход заключался в том, чтобы написать мою собственную версию метода Request.deliverError в приложении:

 @Override public void deliverError(VolleyError error) { if(error.networkResponse == null){ super.deliverError(error); return; }else { switch(error.networkResponse.statusCode){ case HttpStatus.SC_HTTP_VERSION_NOT_SUPPORTED: AppInfo.reportDevInfo(GlideApplication.applicationContext, "got a 505 response for request" +this.toString(), null); break; case HttpStatus.SC_INTERNAL_SERVER_ERROR: case HttpStatus.SC_BAD_GATEWAY: case HttpStatus.SC_SERVICE_UNAVAILABLE: case HttpStatus.SC_GATEWAY_TIMEOUT: int retryCount = RETRY_COUNT - getRetryPolicy().getCurrentRetryCount(); if(retryCount < 0) { super.deliverError(error); return; } String backoff = error.networkResponse.getHeaders.get("Retry-After"); if(TextUtils.isEmpty(backoof) == false) { attemptRetryWithNewBackoff(backoff); return; } break; } super.deliverError(error) } } } 

Но это вызвало только ANR в приложении.

Глядя на дальнейшие исследования, я нашел это сообщение в блоге, которое показало способ обработки различных кодов ответов, единственная проблема, заключается в том, что я не уверен, как обобщать это для всего моего приложения и внедрять обработку кодов ответов 5xx с соответствующими «Retry-After» heade.

Наличие класса, который реализует ErrorListener и получает другой в качестве параметра в конструкторе, кажется очень дорогостоящим и неэффективным:

 public class MyErrorListener implements ErrorListener { ErrorListener mListener; public MyErrorListener(ErrorListener listener) { this.mListener = listener; } @Override public void onErrorResponse(VolleyError error) { if(handleFiveHundredResponse(error) == false) { this.mListener.onErrorResponse(error); } } } 

Я внедрил свой собственный ErrorListener, который обрабатывает ответы об ошибках сервера, вот код:

 public class MyErrorListener implements Response.ErrorListener { Context context; View errorView; TextView errorText; public MyErrorListener(Context context){ this.context = context; } /** * Handle the preparation to show the errors */ public void responsePreparation(){ } /** * Handle the client Errors * @param error */ public void clientErrors(int error){ switch(error) { case 400: errorText.setText(context.getResources().getString(R.string.error_400_registration)); AlertDialog.Builder error400 = new AlertDialog.Builder(context); error400.setTitle(context.getResources().getString(R.string.error_400_title_registration)); error400.setView(errorView); error400.create(); error400.show(); break; case 401: errorText.setText(context.getResources().getString(R.string.error_401_registration)); AlertDialog.Builder error401 = new AlertDialog.Builder(context); error401.setTitle(context.getString(R.string.error_401_title_registration)); error401.setView(errorView); error401.create(); error401.show(); break; } } @Override public void onErrorResponse(VolleyError error) { NetworkResponse response = error.networkResponse; errorView = View.inflate(context, R.layout.error_dialog, null); errorText = (TextView) errorView.findViewById(R.id.error_dialog_text); responsePreparation(); if(response != null && response.data != null){ Log.v("Status code", String.valueOf(error.networkResponse.statusCode)); switch(response.statusCode){ case 400: case 401: clientErrors(response.statusCode); break; case 500: errorText.setText(context.getString(R.string.error_502)); AlertDialog.Builder error500 = new AlertDialog.Builder(context); error500.setTitle(context.getResources().getString(R.string.error_502_title)); error500.setView(errorView); error500.create(); error500.show(); break; case 502: errorText.setText(context.getString(R.string.error_502)); AlertDialog.Builder error502 = new AlertDialog.Builder(context); error502.setTitle(context.getResources().getString(R.string.error_502_title)); error502.setView(errorView); error502.create(); error502.show(); break; } } else{ if(checkConnection()){ errorText.setText(context.getResources().getString(R.string.error_502)); AlertDialog.Builder timeoutErrorServer = new AlertDialog.Builder(context); timeoutErrorServer.setTitle(context.getResources().getString(R.string.error_502_title)); timeoutErrorServer.setView(errorView); timeoutErrorServer.create(); timeoutErrorServer.show(); } else{ errorText.setText(context.getResources().getString(R.string.timeout_error)); AlertDialog.Builder timeoutError = new AlertDialog.Builder(context); timeoutError.setTitle(context.getResources().getString(R.string.timeout_error_title)); timeoutError.setView(errorView); timeoutError.create(); timeoutError.show(); } } } /** * Gets the view of the dialog to show * @return */ public View getDialogView(){ return errorView; } /** * Gets the error text to show * @return */ public TextView getErrorText(){ return errorText; } /** * Checks if the user have got connection * @return Boolean */ private Boolean checkConnection(){ ConnectivityManager conMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo i = conMgr.getActiveNetworkInfo(); return !(i == null || !i.isConnected() || !i.isAvailable()); } } 

Вы можете добавить к коммутатору коды ошибок, которые вы хотите.

Затем, когда я хочу создать новый VolleyQuery, я переопределяю responsePreparation и clientErrors, как этот пример:

 jsObjRequest = new JsonObjectRequest(Request.Method.POST, url, jsonBody, listener, new MyErrorListener(context){ @Override public void responsePreparation() { showProgress(false); } @Override public void clientErrors(int error) { Log.v("Error message", String.valueOf(error)); switch(error) { case 400: getErrorText().setText(context.getResources().getString(R.string.error_400_registration)); AlertDialog.Builder error400 = new AlertDialog.Builder(context); error400.setTitle(context.getResources().getString(R.string.error_400_title_registration)); error400.setView(getDialogView()); error400.create(); error400.show(); break; case 401: getErrorText().setText(context.getResources().getString(R.string.error_401_registration)); AlertDialog.Builder error401 = new AlertDialog.Builder(context); error401.setTitle(context.getString(R.string.error_401_title_registration)); error401.setView(getDialogView()); error401.create(); error401.show(); break; } } });