2016-07-25 21 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); 
} 

Tôi đang cố gắng xác định yêu cầu nào không thành công khi có unique_id.Mã nhận dạng yêu cầu Android Volley trênErrorResponse Mục

Tôi đang gọi hàm getTestDats ("1") với unique_id. Và chức năng được gọi là 10 lần và tất cả các cuộc gọi api trong addToRequestQueue.

Khi API đi vào phần Thành công, nó hoạt động theo mã. Nhưng khi API đi vào phần Lỗi, tôi không nhận dạng được yêu cầu. Có cách nào để biết param yêu cầu của tôi vì vậy tôi có thể thử lại với yêu cầu unique_id cụ thể.

+0

Khi bạn đang gọi yêu cầu, tại thời điểm đó lưu trữ id duy nhất trong một biến toàn cục và sau đó do lỗi bạn có thể dễ dàng sử dụng nó – Vickyexpert

Trả lời

3

thiết lập một trường trong loginRequest và trong onErrorResponse truy cập các lĩnh vực như loginRequest.getUniqueId()

Ngoài ra, tạo ra một lớp riêng biệt mà thực hiện Response.Listener và ErrorListener

đáp ứng Listener lớp:

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 lớp học:

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

Bây giờ gọi nó thích:

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

Bây giờ nếu bạn muốn một số mã của lớp gọi điện thoại để có thể truy cập trong lớp ErrorListener sau đó làm như sau: 1. Trong gọi lớp đặt mã bạn muốn truy cập trong các phương pháp 2. Tạo một giao diện với những phương pháp 3. lớp gọi sẽ thực hiện giao diện mà 4. Vượt qua giao diện để xây dựng các MyErrorListener hoặc MyResponseListener

ví dụ một hoạt động kêu gọi yêu cầu chuyền, về lỗi bạn muốn hiển thị một tin nhắn. đặt mà hiển thị mã lỗi trong một phương pháp:

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

nay tạo ra một giao diện

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

các activity sẽ thực hiện errorMessageInterface và chuyển thông tin này đến các nhà xây dựng của MyErrorListener và lưu nó trong một field.

Bên onErrorResponse, bạn sẽ gọi

field.showMessage() 
1

Chỉ cần thêm mã này để xác định loại lỗi bạn đang facing.Add này trong onerror của bạn() phương pháp:

  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

Log các unique_id trước khi đưa ra tức là yêu cầu; sau params.put("unique_id", unique_id);//1,2,3,4,5. Và cũng một khi bạn nhận được phản hồi theo phương thức onResponse(). Và cross xác minh chính xác những gì đang xảy ra.

3

Bạn có thể phân tích phản ứng lỗi trong cùng một cách như bạn phân tích phản ứng thành công. Tôi sử dụng giải pháp tương tự trong các dự án của mình.

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

Sử dụng:

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

hầu hết các giải pháp ở đây sẽ "làm việc" nhưng chúng quá phức tạp .. cho tôi :) đây là lựa chọn đơn giản nhất với sự thay đổi mã ít nhất tôi có thể nghĩ đến :

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

Tất cả câu trả lời ở trên có vẻ đúng. Nhưng tôi khuyên bạn nên làm điều này một cách tối ưu. Nếu bạn sẽ thêm mã xử lý lỗi trong tất cả onErrorResponse() thì nó sẽ tạo bản sao. Vì vậy, hãy tạo riêng method trong Utils hoặc một số khác class và chỉ cần gọi method bằng cách chuyển error object tới method. Ngoài ra, bạn có thể tăng số lượng dialog hoặc toast để hiển thị số 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

Tôi nghĩ bạn phải tạo một phương thức conman trên lớp Cơ sở. Như được đưa ra dưới đây mà tôi sử dụng trong mã của tôi để gọi 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); 
    } 
} 

Hãy lưu ý rằng ở đây chúng tôi làm cho một giao diện để nhận được phản hồi và lỗi. Sử dụng Giao diện, bạn có thể nhận tên phương thức trên cả phản hồi và lỗi để bạn có thể xác định api web nào được gọi thành công và lỗi nào cung cấp lỗi. Bạn nên mở rộng lớp cơ sở thành Hoạt động và cũng triển khai Giao diện mà bạn đã thực hiện để nhận phản hồi volley. Ở đây trong đoạn mã trên tôi cho thấy cách liên kết giao diện với hoạt động. khi bạn gọi api bằng cách chuyển ngữ cảnh hoạt động.

Các vấn đề liên quan