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

Próbuję tożsamości, która nie powiodła się prośba o konieczności unique_id.Android Volley Zapytanie Identity onErrorResponse Sekcja

Nazywam funkcję getTestDats ("1") z unique_id. I funkcja o nazwie 10 razy i wszystkie wywołania api w addToRequestQueue.

Kiedy API przechodzi do części Sukces, działa zgodnie z kodem. Ale kiedy API przechodzi do części Błąd, nie udało mi się zidentyfikować żądania. Czy jest jakiś sposób, aby poznać mój parametr żądania, aby móc spróbować ponownie z konkretnym żądaniem unique_id.

+0

Gdy wywołujesz żądanie, przechowuj unikatowy identyfikator w jednej zmiennej globalnej, a następnie przy błędzie, możesz z niego łatwo korzystać – Vickyexpert

Odpowiedz

3

ustawić pole w loginRequest aw onErrorResponse dostępem pole jak loginRequest.getUniqueId()

Alternatywnie, oddzielna utworzyć klasę, która implementuje Response.Listener i ErrorListener

Response Listener klasy:

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 klasa:

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

Teraz nazywają to lubią:

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

Teraz, jeśli chcesz jakiś kod klasy wywołującego, aby były dostępne w klasie ErrorListener następnie wykonaj następujące czynności: 1. W nazywając klasa umieścić kody chcesz uzyskać dostęp do w metodach 2. Utwórz interfejs z tych metod 3. Klasa wywołujący będzie wdrożyć ten interfejs 4. Przełożyć interfejs do konstruktora MyErrorListener lub MyResponseListener

na przykład aktywność wywołuje żądanie siatkówkę, na błędzie chcesz pokazać wiadomość. put, które pokazują kody błędów w metodzie:

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

teraz utworzyć interfejs

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

activity będzie realizować errorMessageInterface i przekazać do konstruktora MyErrorListener i zapisać go w field.

Wewnątrz onErrorResponse, można nazwać

field.showMessage() 
1

Wystarczy dodać ten kod, aby określić, który typ błędu jesteś facing.Add to w onError() metoda:

  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

Zaloguj się unique_id przed dokonaniem żądania tj; po params.put("unique_id", unique_id);//1,2,3,4,5. A także po uzyskaniu odpowiedzi w metodzie onResponse(). I sprawdź, co dokładnie się dzieje.

3

Można analizować odpowiedź o błędzie w taki sam sposób, jak przeanalizować odpowiedzi sukces. Używam podobnego rozwiązania w moich projektach.

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

Zastosowanie:

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

większość rozwiązań tutaj będzie „działać”, ale są one zbyt skomplikowane dla mnie .. :) Oto najprostsza opcja z najmniejszej zmiany kodu mogę myśleć :

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

Wszystkie powyższe odpowiedzi wydają się poprawne. Zalecam jednak, aby zrobić to w zoptymalizowany sposób. Jeśli dodasz kod obsługi błędów we wszystkich onErrorResponse(), utworzy to duplikację. Stwórz więc oddzielne method w Utils lub inne class i po prostu wywołaj method przekazując error object do . Możesz również nadmuchać niektóre modele: dialog lub toast, aby wyświetlić 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

Myślę, że musisz zrobić jedną metodę conman na klasie bazowej. Jak podano ryk który użyłem w moim kodu do wywoływania 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); 
    } 
} 

Proszę zauważyć, że tutaj robimy jeden interfejs dla uzyskiwanie odpowiedzi i błędów. Za pomocą interfejsu można uzyskać nazwę metody zarówno w odpowiedzi, jak i po błędzie, dzięki czemu można zidentyfikować, które połączenie internetowe zostało pomyślnie wywołane i które powoduje błąd. Powinieneś rozszerzyć klasę bazową na Aktywność, a także zaimplementować Interfejs, który przygotowałeś do uzyskania odpowiedzi na salwę. Tutaj w powyższym kodzie pokazuję jak powiązać interfejs z działaniem. kiedy wywołujesz api, przekazując kontekst działania.

Powiązane problemy