2016-07-25 107 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時。