Handle Volley error

2020-02-02 04:56发布

问题:

I want to handle and show some message in onErrorResponse

below is my code.

String url = MainActivity.strHostUrl+"api/delete_picture"; 
jobjDeleteImage = new JsonObjectRequest(Request.Method.POST, url, jobj, new Response.Listener<JSONObject>() {

    @Override
    public void onResponse(JSONObject response) {
        Log.e("Image response", response.toString());


    }
},  new Response.ErrorListener() {

    @Override
    public void onErrorResponse(VolleyError error) {

        Log.e("Volly Error", error.toString());

        NetworkResponse networkResponse = error.networkResponse;
        if (networkResponse != null) {
            Log.e("Status code", String.valueOf(networkResponse.statusCode));
        }
    }
});

I want to handle com.android.volley.TimeoutError and also some other error code like 404, 503 etc and Toast message here.

回答1:

The networkResponse is null because in a TimeoutError no data is received from the server -- hence the timeout. Instead, you need generic client side strings to display when one of these events occur. You can check for the VolleyError's type using instanceof to differentiate between error types since you have no network response to work with -- for example:

@Override
public void onErrorResponse(VolleyError error) {

    if (error instanceof TimeoutError || error instanceof NoConnectionError) {
        Toast.makeText(context,
                context.getString(R.string.error_network_timeout),
                Toast.LENGTH_LONG).show();
    } else if (error instanceof AuthFailureError) {
        //TODO
    } else if (error instanceof ServerError) {
       //TODO
    } else if (error instanceof NetworkError) {
      //TODO
    } else if (error instanceof ParseError) {
       //TODO
    }
}


回答2:

This is what I am using in my projects.

        @Override
        public void onErrorResponse(VolleyError error) {
            if(error instanceof NoConnectionError){
                ConnectivityManager cm = (ConnectivityManager)mContext
                        .getSystemService(Context.CONNECTIVITY_SERVICE);
                NetworkInfo activeNetwork = null;
                if (cm != null) {
                    activeNetwork = cm.getActiveNetworkInfo();
                }
                if(activeNetwork != null && activeNetwork.isConnectedOrConnecting()){
                    Toast.makeText(getActivity(), "Server is not connected to internet.",
                            Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(getActivity(), "Your device is not connected to internet.",
                            Toast.LENGTH_SHORT).show();
                }
            } else if (error instanceof NetworkError || error.getCause() instanceof ConnectException 
                    || (error.getCause().getMessage() != null 
                    && error.getCause().getMessage().contains("connection"))){
                Toast.makeText(getActivity(), "Your device is not connected to internet.", 
                        Toast.LENGTH_SHORT).show();
            } else if (error.getCause() instanceof MalformedURLException){
                Toast.makeText(getActivity(), "Bad Request.", Toast.LENGTH_SHORT).show();
            } else if (error instanceof ParseError || error.getCause() instanceof IllegalStateException
                    || error.getCause() instanceof JSONException
                    || error.getCause() instanceof XmlPullParserException){
                Toast.makeText(getActivity(), "Parse Error (because of invalid json or xml).", 
                        Toast.LENGTH_SHORT).show();
            } else if (error.getCause() instanceof OutOfMemoryError){
                Toast.makeText(getActivity(), "Out Of Memory Error.", Toast.LENGTH_SHORT).show();
            }else if (error instanceof AuthFailureError){
                Toast.makeText(getActivity(), "server couldn't find the authenticated request.", 
                        Toast.LENGTH_SHORT).show();
            } else if (error instanceof ServerError || error.getCause() instanceof ServerError) {
                Toast.makeText(getActivity(), "Server is not responding.", Toast.LENGTH_SHORT).show();
            }else if (error instanceof TimeoutError || error.getCause() instanceof SocketTimeoutException
                    || error.getCause() instanceof ConnectTimeoutException 
                    || error.getCause() instanceof SocketException
                    || (error.getCause().getMessage() != null 
                    && error.getCause().getMessage().contains("Connection timed out"))) {
                Toast.makeText(getActivity(), "Connection timeout error", 
                        Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(getActivity(), "An unknown error occurred.", 
                        Toast.LENGTH_SHORT).show();
            }
        }


回答3:

You have TimeoutError and NoConnectionError as well. Super useful.



回答4:

you can handle the volley quick response with custom volley class like this: Volley class:

import android.content.Context;
import android.graphics.Bitmap;
import android.text.TextUtils;
import android.util.LruCache;

import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;

import static android.content.ContentValues.TAG;

public class VolleyClass {
    private static VolleyClass mInstance;
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
    private Context mCtx;
    private int time = 0;

    public VolleyClass(Context context) {
        mCtx = context;
        mRequestQueue = getRequestQueue();

        mImageLoader = new ImageLoader(mRequestQueue,
                new ImageLoader.ImageCache() {
                    private final LruCache<String, Bitmap>
                            cache = new LruCache<>(20);

                    @Override
                    public Bitmap getBitmap(String url) {
                        return cache.get(url);
                    }

                    @Override
                    public void putBitmap(String url, Bitmap bitmap) {
                        cache.put(url, bitmap);
                    }
                });
    }

    public static synchronized VolleyClass getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new VolleyClass(context);
        }
        return mInstance;

    }

    public <T> void addToRequestQueue(Request<T> req, String tag) {
        // set the default tag if tag is empty
        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        req.setRetryPolicy(new DefaultRetryPolicy(
                time,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

        getRequestQueue().add(req);
    }

    private RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            // getApplicationContext() is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.
            //mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
         mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext(), new OkHttpStack(new com.squareup.okhttp.OkHttpClient()));
        }
        return mRequestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req) {

        req.setRetryPolicy(new DefaultRetryPolicy(
                time,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        getRequestQueue().add(req);
    }




    /*public ImageLoader getImageLoader() {
        return mImageLoader;
    }*/
}

Sinc gradle with compile 'com.android.volley:volley:1.0.0' compile 'com.squareup.okhttp3:okhttp:3.8.1'

Initialise the volley class: VolleyClass volleyClass; volleyClass = new VolleyClass(this); // under onCreate then call the method for operation 1.row data:

    private void serverCall() {
        final ProgressDialog mDialog = new ProgressDialog(SettingActivity.this);
        mDialog.setMessage("Please wait...");
        mDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        mDialog.setIndeterminate(true);
        mDialog.setCancelable(false);
        mDialog.show();


        JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.GET, "your url", null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {


                mDialog.dismiss();


            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                // TODO Auto-generated method stub
                mDialog.dismiss();

            }
        }) {

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                HashMap<String, String> headers = new HashMap<String, String>();
                headers.put("Content-Type", "application/json; charset=utf-8");
                headers.put("User-agent", System.getProperty("http.agent"));
                return headers;
            }

            @Override
            public Priority getPriority() {
                return Priority.IMMEDIATE;
            }
        };

        volleyClass.addToRequestQueue(jsObjRequest);

    }

private void networkCallPostData() {

    StringRequest stringRequest = new StringRequest(Request.Method.POST, "url",

            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    Log.e("response", response);

                }
            }, new Response.ErrorListener() {

        @Override
        public void onErrorResponse(VolleyError error) {

            System.out.println("VolleyError " + error.getMessage());
        }
    }) {
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<String, String>();
            params.put("id",app.getAppSettings().__uId);
            return params;
        }

        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            HashMap<String, String> headers = new HashMap<String, String>();
            //headers.put("Content-Type", "application/json; charset=utf-8");
            headers.put("Content-Type", "multipart/form-data");
            headers.put("User-agent", System.getProperty("http.agent"));
            return headers;
        }

        @Override
        public Priority getPriority() {
            return Priority.IMMEDIATE;
        }

    };
    volleyClass.addToRequestQueue(stringRequest);
}



回答5:

Read more about Volley Error handling at Android Volley example with Error Handling

Every Volley requests has two callbacks -one for success and one for failure.Based on the type of VolleyError parameter in the onErrorResponse callback developers can show a sensible message to the users as shown below

@Override
public void onErrorResponse (VolleyError error){

   if (error instanceof TimeoutError || error instanceof NoConnectionError) {
     //This indicates that the reuest has either time out or there is no connection

   } else if (error instanceof AuthFailureError) {
     // Error indicating that there was an Authentication Failure while performing the request

   } else if (error instanceof ServerError) {
     //Indicates that the server responded with a error response

   } else if (error instanceof NetworkError) {
     //Indicates that there was network error while performing the request

   } else if (error instanceof ParseError) {
      // Indicates that the server response could not be parsed

   }
}


回答6:

/**
 * Http 访问失败
 * 
 * 
 */
@Override
public void error(VolleyError error){

     NetworkResponse response = error.networkResponse;
     if(response != null && response.data != null){
        Toast.makeText(context,"errorMessage:"+response.statusCode, Toast.LENGTH_SHORT).show();
     }else{
        String errorMessage=error.getClass().getSimpleName();       
        if(!TextUtils.isEmpty(errorMessage)){
            Toast.makeText(context,"errorMessage:"+errorMessage, Toast.LENGTH_SHORT).show();
        }
     }

}//public void error(VolleyError error) is over!  zlb