Android Volley请求标识onErrorResponse部分

时间:2016-07-25 11:15:21

标签: android api android-volley

public void getTestDats(String unique_id) {
    final String tag = "testList";
    String url = Constants.BASE_URL + "test_module.php";
    Map<String, String> params = new HashMap<String, String>();
    params.put("user_id", SharedPreferenceUtil.getString(Constants.PrefKeys.PREF_USER_ID, "1"));
    params.put("unique_id", unique_id);//1,2,3,4,5
    DataRequest loginRequest = new DataRequest(Method.POST, url, params, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            switch (response.optInt("unique_id")) {
                case 1:
                    //task 1
                    break;
                case 2:
                    //task 2
                    break;
                default:
                    //nothing
            }
        }
    }, new ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
                //I want to know which unique_id request is failed 
        }
    });
    loginRequest.setRetryPolicy(new DefaultRetryPolicy(20000, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    AppController.getInstance().addToRequestQueue(loginRequest, tag);
} 

我正在尝试使用unique_id识别哪个请求失败。

我用unique_id调用getTestDats(“1”)函数。函数调用10次,所有api调用addToRequestQueue。

当API进入Success部分时,它按照代码工作。 但是当API进入错误部分时,我没有识别请求。 有没有办法知道我的请求参数,所以我可以使用特定的unique_id请求重试。

7 个答案:

答案 0 :(得分:3)

loginRequestonErrorResponse中设置字段,访问loginRequest.getUniqueId()

字段

或者,创建一个实现Response.Listener和ErrorListener

的单独类

Response Listener类:

public class MyReponseListener implements Response.Listener<JSONOBject>{
    private long uniqId;
    public MyResponseListener(long uniqId){
        this.uniqId = uniqId;
    }

    @Override
    public void onResponse(JSONObject response) {
        System.out.println("response for uniqId " + uniqId);
        // do your other chit chat
    }
}

ErrorListener类:

public class MyErrorListener implements ErrorListener{
        private long uniqId;
        public MyErrorListener(long uniqId){
            this.uniqId = uniqId;
        }

        @Override
        public void onErrorResponse(VolleyError error) {
             System.out.println("Error for uniqId : " + uniqId);
        }
}

现在称之为:

DataRequest loginRequest = new DataRequest(Method.POST, url, params, new MyResponeListener(uniqId), new MyErrorListener(uniqId));

现在,如果您希望在ErrorListener类中可以访问调用类的某些代码,请执行以下操作: 1.在调用类时,将要访问的代码放入方法中 2.使用这些方法创建接口 3.调用类将实现该接口 4.将接口传递给MyErrorListener或MyResponseListener

的构造函数

例如,当您想要显示消息时,活动会调用排球请求。 把那个显示错误代码放在一个方法中:

public void showMessage(int errorCode){
    //message according to code
}

现在创建一个界面

public interface errorMessageInterface{
    void showMessage(int errorCode);
}

activity将实施errorMessageInterface并将其传递给MyErrorListener的构造函数并将其保存在field中。

onErrorResponse内,您将致电

field.showMessage()

答案 1 :(得分:3)

您可以使用与解析成功响应相同的方式解析错误响应。我在我的项目中使用了类似的解决方案。

public class VolleyErrorParser {
    private VolleyError mError;
    private String mBody;
    private int mUniqueId = -1;
    public VolleyErrorParser(VolleyError e){
        mError = e;
        parseAnswer();
        parseBody();
    }

    private void parseBody() {
        if (mBody==null)
            return;
        try{
            JSONObject response = new JSONObject(mBody);
            mUniqueId = response.getOptInt("unique_id");

        }catch (JSONException e){
            e.printStackTrace();
        }
    }

    private void parseAnswer() {
        if (mError!=null&&mError.networkResponse!=null&&mError.networkResponse.data!=null){
            mBody = new String(mError.networkResponse.data);
        }
    }
    public String getBody(){
        return mBody;
    }
    public int getUniqueId(){
        return mUniqueId;
    }
}

使用:

...
, new ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            int id = new VolleyErrorParse(error).getUniqueId();
            switch (id) {
                case -1:
                     //unique id not found in the answer
                     break;
                case 1:
                    //task 1
                    break;
                case 2:
                    //task 2
                    break;
                default:
                    //nothing
            }        
        }
    }
...

答案 2 :(得分:1)

只需添加此代码即可识别您所面临的错误类型。在onError()方法中添加此代码:

         if (error instanceof TimeoutError) {
            Log.e(TAG, "TimeoutError");
        } else if (error instanceof NoConnectionError) {
            Log.e(TAG,"tNoConnectionError");
        } else if (error instanceof AuthFailureError) {
            Log.e(TAG,"AuthFailureError");
        } else if (error instanceof ServerError) {
            Log.e(TAG,"ServerError");
        } else if (error instanceof NetworkError) {
            Log.e(TAG,"NetworkError");
        } else if (error instanceof ParseError) {
            Log.e(TAG,"ParseError");
        }

答案 3 :(得分:1)

在提出请求之前记录unique_id,即;在params.put("unique_id", unique_id);//1,2,3,4,5之后。并且一旦您以onResponse()方法获得响应。并交叉验证究竟发生了什么。

答案 4 :(得分:1)

这里的大部分解决方案都会“起作用”,但它们太复杂了......对我来说:) 这是最简单的选项,我能想到的代码更改最少:

...
final Map<String, String> params = new HashMap<String, String>();
    params.put("user_id", SharedPreferenceUtil.getString(Constants.PrefKeys.PREF_USER_ID, "1"));
params.put("unique_id", unique_id);//1,2,3,4,5
DataRequest loginRequest = new DataRequest(Method.POST, url, params, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            switch (params.get("unique_id")) {
                case 1:
                    //task 1
                    break;
                case 2:
                    //task 2
                    break;
                default:
                    //nothing
            }
        }
...

答案 5 :(得分:1)

以上所有答案似乎都是正确的。但我建议您以优化的方式执行此操作。如果您要在所有onErrorResponse()中添加错误处理代码,那么它将创建重复。因此,在method或其他Utils中创建一个单独的class,然后将method传递给error object,然后调用method。此外,您可以对某些dialogtoast进行通知,以显示error message

public static void handleError(final Context context, String alertTitle,
                               Exception exception, String logTag) {
    if (context != null) {
        if (exception instanceof TimeoutError)
            message = context.getString(R.string.TimeoutError);
        else if (exception instanceof NoConnectionError)
            message = context.getString(R.string.NoConnectionError);
        else if (exception instanceof AuthFailureError)
            message = context.getString(R.string.AuthFailureError);
        else if (exception instanceof ServerError)
            message = context.getString(R.string.ServerError);
        else if (exception instanceof NetworkError)
            message = context.getString(R.string.NetworkError);
        else if (exception instanceof ParseError)
            message = context.getString(R.string.ParseError);        

            message = exception.getMessage();


                DialogHelper.showCustomAlertDialog(context, null,
                        alertTitle, message, "ok",
                        new OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog,
                                                int which) {

                            }
                        }, null, null);


        }
    }

答案 6 :(得分:1)

我认为你必须在Base类上创建一个conman方法。正如我在我的代码中用来调用php web api

所给出的那样
    /**
 * <h1>  Use for calling volley webService </h1>
 *
 * @param cContext         Context of activity from where you call the webService
 * @param mMethodType      Should be POST or GET
 * @param mMethodname      Name of the method you want to call
 * @param URL              Url of your webService
 * @param mMap             Key Values pairs
 * @param initialTimeoutMs Timeout of webService in milliseconds
 * @param shouldCache      Web Api response are stored in catch(true) or not(false)
 * @param maxNumRetries    maximum number in integer for retries to execute webService
 * @param isCancelable     set true if you set cancel progressDialog by user event
 * @param aActivity        pass your activity object
 */

public void callVolley(final Context cContext, String mMethodType, final String mMethodname, String URL,
                       final HashMap<String, String> mMap, int initialTimeoutMs, boolean shouldCache, int maxNumRetries,
                       Boolean isProgressDailogEnable, Boolean isCancelable, final Activity aActivity) {

    mMap.put("version_key_android",BuildConfig.VERSION_NAME+"");
    if (!isOnline(cContext)) {
        //showErrorDailog(aActivity, Constant.PleaseCheckInternetConnection, R.drawable.icon);
    } else {
        StringRequest jsObjRequest;
        int reqType = 0;
        String RequestURL = URL.trim();
        queue = Volley.newRequestQueue(cContext);

        if (isProgressDailogEnable) {
            customLoaderDialog = new CustomLoaderDialog(cContext);
            customLoaderDialog.show(isCancelable);

            customLoaderDialog.dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {
                    //  finish();
                }
            });
        }
        if (mMethodType.trim().equalsIgnoreCase("GET"))
            reqType = com.android.volley.Request.Method.GET;
        else if (mMethodType.trim().equalsIgnoreCase("POST"))
            reqType = com.android.volley.Request.Method.POST;

        if (RequestURL.equals(""))
            RequestURL = Constant.BASE_URL;
        else
            RequestURL = URL;

        if (Constant.d) Log.d("reqType", reqType + "");
        jsObjRequest = new StringRequest(reqType, RequestURL, new com.android.volley.Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                if (Constant.d) Log.d("response==>" + mMethodname, "" + response);
                if (customLoaderDialog != null) {
                    try {
                        customLoaderDialog.hide();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                if (response == null || response.length() == 0) {
                    IVolleyRespose iVolleyRespose = (IVolleyRespose) aActivity;
                    iVolleyRespose.onVolleyResponse(404, response, mMethodname);
                } else {

                    JSONObject json_str;
                    try {
                        json_str = new JSONObject(response);
                        int status = json_str.getInt("status");

                        if (status == 100) {

                            AlertDialog alertDialog = new AlertDialog.Builder(aActivity).create();
                            alertDialog.setTitle(getResources().getString(R.string.app_name));
                            alertDialog.setMessage(json_str.getString("message") + "");
                            alertDialog.setCancelable(false);
                            alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
                                    new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog, int which) {
                                            try {
                                                Intent viewIntent =
                                                        new Intent("android.intent.action.VIEW",
                                                                Uri.parse(Constant.playStoreUrl));
                                                startActivity(viewIntent);
                                            }catch(Exception e) {
                                                Toast.makeText(getApplicationContext(),"Unable to Connect Try Again...",
                                                        Toast.LENGTH_LONG).show();
                                                e.printStackTrace();
                                            }
                                           dialog.dismiss();
                                           // return;
                                        }
                                    });
                            alertDialog.show();
                        } else {
                            IVolleyRespose iVolleyRespose = (IVolleyRespose) aActivity;
                            iVolleyRespose.onVolleyResponse(RESPONSE_OK, response, mMethodname);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }, new com.android.volley.Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError arg0) {
                // TODO Auto-generated method stub
                IVolleyRespose iVolleyError = (IVolleyRespose) aActivity;
                iVolleyError.onVolleyError(404, "Error", mMethodname);

                if (customLoaderDialog != null) {
                    customLoaderDialog.hide();
                }

            }
        }) {
            @Override
            protected Map<String, String> getParams() {
                String strRequest = "";
                try {
                    strRequest = getWebservicejsObjRequestforvolley(mMethodname, mMap);
                    if (Constant.d) Log.d("Request==>", strRequest + "");
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                Map<String, String> params = new HashMap<>();
                params.put("json", strRequest);

                return params;
            }

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String, String> params = new HashMap<>();
                params.put("Content-Type", "application/x-www-form-urlencoded");
                return params;
            }
        };
        //if(Constant.d) Log.d("Request==>", jsObjRequest+"");
        jsObjRequest.setTag(mMethodname);
        jsObjRequest.setShouldCache(shouldCache);

        jsObjRequest.setRetryPolicy(new DefaultRetryPolicy(initialTimeoutMs, maxNumRetries, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        queue.add(jsObjRequest);
    }
}

请注意,我们在此处创建了一个用于获取响应和错误的界面。 使用Interface,您可以获得响应和错误的方法名称,以便您可以识别成功调用哪个Web api以及哪个给出错误。您应该将基类扩展为Activity,并实现为获取齐射响应而生成的接口。在上面的代码中,我展示了如何将接口绑定到activity。当你通过传递活动背景来调用api时。