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