排球错误处理一般化

the*_*osh 5 android httpresponse android-volley

在我的应用程序中,我一直在考虑从服务器实现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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但这只会在应用程序中引起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);
        }
    } 

}
Run Code Online (Sandbox Code Playgroud)

dav*_*vid 0

我已经实现了自己的 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());
    }

}
Run Code Online (Sandbox Code Playgroud)

您可以向交换机添加所需的错误代码。

然后,当我想要创建一个新的 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;
            }

        }
    });
Run Code Online (Sandbox Code Playgroud)