【问题标题】:Android Volley Request Identity onErrorResponse SectionAndroid Volley 请求标识 onErrorResponse 部分
【发布时间】:2016-11-28 17:01:32
【问题描述】:
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 次,并且 addToRequestQueue 中的所有 api 调用。

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

【问题讨论】:

  • 当你调用request时,将唯一的id存储在一个全局变量中,然后在出错时你可以轻松使用它

标签: android api android-volley


【解决方案1】:

loginRequest 中设置一个字段并在onErrorResponse 中访问该字段,如loginRequest.getUniqueId()

或者,创建一个单独的类来实现 Response.Listener 和 ErrorListener

响应监听类:

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 的构造函数

例如,活动调用 volley 请求,出错时您想显示一条消息。 将显示错误代码放入方法中:

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

现在创建一个界面

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

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

onErrorResponse里面,你会调用

field.showMessage()

【讨论】:

    【解决方案2】:

    您可以像解析成功响应一样解析错误响应。我在我的项目中使用了类似的解决方案。

    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
                }        
            }
        }
    ...
    

    【讨论】:

      【解决方案3】:

      只需添加此代码即可识别您所面临的错误类型。在您的 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");
              }
      

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

          这里的大多数解决方案都可以“工作”,但它们太复杂了……对我来说 :) 这是我能想到的代码更改最少的最简单选项:

          ...
          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
                      }
                  }
          ...
          

          【讨论】:

            【解决方案6】:

            以上所有答案似乎都是正确的。但我建议您以优化的方式执行此操作。如果您将在所有onErrorResponse() 中添加错误处理代码,那么它将创建重复。因此,在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);
            
            
                    }
                }
            

            【讨论】:

              【解决方案7】:

              我认为你必须在 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);
                  }
              }
              

              请注意,这里我们制作了一个用于获取响应和错误的接口。 使用接口,您可以获取响应和错误的方法名称,以便您可以识别成功调用了哪个 web api 以及哪个给出了错误。您应该将基类扩展到 Activity 并实现您为获得凌空响应而制作的接口。在上面的代码中,我展示了如何将接口绑定到活动。当您通过传递活动上下文调用 api 时。

              【讨论】:

                猜你喜欢
                • 2014-08-31
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-05-17
                相关资源
                最近更新 更多