2016-07-25 103 views
12
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标识哪个请求失败。Android Volley请求身份onErrorResponse部分

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

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

+0

当您调用请求时,此时将唯一标识存储在一个全局变量中,然后发生错误,您可以轻松使用它 – Vickyexpert

回答

3

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

领域可替代地,创建实现Response.Listener和ErrorListener

响应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

只需添加以下代码,以确定你在你的onError facing.Add这种错误的类型()方法:

  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"); 
     } 
1

发出请求之前,即在登录unique_id;在params.put("unique_id", unique_id);//1,2,3,4,5之后。而且一旦你得到onResponse()方法的回应。并交叉验证究竟发生了什么。

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

以上所有答案似乎是正确的。但我建议你以优化的方式做到这一点。如果您将在所有onErrorResponse()中添加错误处理代码,那么它将创建重复。因此,在Utils或其他class中创建一个单独的method,并通过将error object传递给method来调用该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); 


     } 
    } 
1

我认为你必须在Base类上做一个conman方法。作为给定的波纹管,我在我的代码用于调用PHP网页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并且还实现您为获得齐次响应而​​创建的Interface。在上面的代码中,我展示了如何将接口绑定到活动。当你通过传递活动上下文来调用API时。