Как получить код состояния с сервера в Android с помощью volley?

#android #android-volley

Вопрос:

Мне нужно получить код состояния из restful api после выполнения запроса с Android и обновить свой пользовательский интерфейс в соответствии с ответом на статус. Я использую Android volley для выполнения запросов.

Я инициализировал переменную-член и инициализировал 0 в методе onCreate.

private int deleteStatus

Вот метод, который обрабатывает удаление из api и обновляет deleteStatus переменную.

 public int handleDeletePet(int petId) {   String url = "myurl";   StringRequest request = new StringRequest(Request.Method.DELETE, url   petId, new Response.Listenerlt;Stringgt;() {  @Override  public void onResponse(String response) {  }  }, new Response.ErrorListener() {  @Override  public void onErrorResponse(VolleyError error) {  error.printStackTrace();  }  }){  @Override  protected Responselt;Stringgt; parseNetworkResponse(NetworkResponse response) {  if(response != null) {  deleteStatus = response.statusCode;  }  Log.i("deleted status : ", String.valueOf(deleteStatus));   return super.parseNetworkResponse(response);  }   };  MySingletonRequestQueue.getInstance(this.getActivity()).addToRequestQueue(request);   Log.i("status before returning : ", String.valueOf(deleteStatus));  return deleteStatus;  }  

Вот где я получаю значение int, возвращенное вышеуказанным handleDeletePet методом, и пытаюсь выполнить обновления пользовательского интерфейса по мере необходимости.

 int returnedDeleteStatus = handleDeletePet(currentPet.getPetId()); Log.i("returned status ", String.valueOf(returnedDeleteStatus)); if (returnedDeleteStatus == 200) {  myPetsList.remove(currentPet);  myPetsAdapter.notifyItemRemoved(position);  Snackbar.make(myPetsRecyclerView, "Deleted Pet "   currentPet.getPetName(), Snackbar.LENGTH_LONG).show();  } else {  Snackbar.make(myPetsRecyclerView, "Cannot delete "   currentPet.getPetName()   " since it has events", Snackbar.LENGTH_LONG).show();  myPetsAdapter.notifyItemChanged(position);  }  

Это то, что показывает журнал для значений ответа на статус

 I/status before returning :: 0 I/returned status: 0 D/EGL_emulation: eglMakeCurrent: 0x9c0850c0: ver 3 0 (tinfo 0x9c0830e0) D/EGL_emulation: eglMakeCurrent: 0x9c0850c0: ver 3 0 (tinfo 0x9c0830e0) I/deleted status :: 200  

Значение отображается правильно только внутри parseNetworkResponse , и когда я возвращаю его даже при правильном удалении, оно показывает 0 снаружи. Кроме того, порядок, в котором печатается журнал, странный. Сначала он должен напечататься delete status , потом status before returning : потом returned status . Но он печатается в неправильном порядке, как указано выше. Может быть, это связано с тем, что для возврата значения с сервера требуется время? Как мне это исправить?

Ответ №1:

Журналы печатаются не в неправильном порядке, вы правы, что для возврата значения с сервера требуется время. Простым способом убедиться, что у вас есть это значение кода ответа для вашего пользовательского интерфейса, было бы создать свой собственный интерфейс / обратный вызов для обработки ответа сервера. Затем передайте экземпляр этого интерфейса вашему методу, который выполняет сетевой вызов, обрабатывая ответ через этот экземпляр. Интерфейс может выглядеть следующим образом:

 public interface GenericCallback {  /**  * return your response code, or any other data you need here  * or in any number of methods you wish to implement  */  default String onServerCodeResponse(String response) {  return response;  } }  

Затем вы изменили бы свой метод, чтобы принять экземпляр этого обратного вызова / интерфейса:

 public int handleDeletePet(int petId, GenericCallback callback) {   String url = "myurl";   StringRequest request = new StringRequest(Request.Method.DELETE, url   petId, new Response.Listenerlt;Stringgt;() {  @Override  public void onResponse(String response) {  }  }, new Response.ErrorListener() {  @Override  public void onErrorResponse(VolleyError error) {  error.printStackTrace();  }  }) {  @Override  protected Responselt;Stringgt; parseNetworkResponse(NetworkResponse response) {  if (response != null) {  deleteStatus = response.statusCode;  }  Log.i("deleted status : ", String.valueOf(deleteStatus));  //return the code through your callback / interface instance  callback.onServerCodeResponse(deleteStatus);    return super.parseNetworkResponse(response);  }   };  MySingletonRequestQueue.getInstance(this.getActivity()).addToRequestQueue(request);   Log.i("status before returning : ", String.valueOf(deleteStatus));  return deleteStatus; }  

Теперь при вызове этой функции вы можете либо сначала создать экземпляр GenericCallback и перейти к методу, либо создать на лету, как это:

 handleDeletePet(1, new GenericCallback() {  @Override  public String onServerCodeResponse(String response) {  //you now have the code here, update your UI  updateUiFunction(response);  return null;  }  });