Как получить POJO из залпового обратного вызова и использовать / вернуть его в вызывающей функции? - PullRequest
0 голосов
/ 07 июля 2019

Я реализую простое мобильное приложение с учетными записями пользователей. Кроме того, он должен быть структурирован в многоуровневой архитектуре, которая четко разделяет представление, логику и доступ к базе данных. В настоящее время я могу отправлять и получать данные с сервера, используя библиотеку залпов. Однако эти данные доступны только внутри метода onResponse Response.Listener<String>, переданного в качестве параметра в конструкторе объекта stringRequest, который впоследствии использовался для выполнения запроса. Я хочу использовать данные, полученные в ответе, для создания объекта User, который мог бы использовать во всем приложении, и максимально сохранить многоуровневую архитектуру.

Это пример метода, к которому я стремился:

public ResponseType insertUser (final Context context, final String id, final String name, final String password) {

    //using a wrapper object because have to declare object as final to use
        //inside inner class, so use field to assign value
    final ResponseWrapper wrapper = new ResponseWrapper();

    StringRequest stringRequest = new StringRequest(Request.Method.POST, BuildConfig.ip,
            new Response.Listener<String>() {

                @Override
                public void onResponse(String response) {

                    wrapper.response = response.equals("") ?
                                        ResponseWrapper.SUCCESS :
                                        ResponseWrapper.DB_ERROR;
                }
            },
            new Response.ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {

                    wrapper.response = ResponseWrapper.CONNECTION_ERROR;
                }
        }){
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {

                Map<String,String> params = new HashMap<String,String>();
                params.put("id",id);
                params.put("name",name);
                params.put("password",password);
                return params;
            }
        };

    RequestQueue requestQueue = Volley.newRequestQueue(context);
    requestQueue.add(stringRequest);

    //waiting for callback to modify field
    while(wrapper.response == null);

    return wrapper.response;
}

Я попытался установить поле внешнего объекта внутри onResponse, ожидая изменения поля для продолжения выполнения, но безрезультатно. Код компилирует и выполняет запрос, но поле остается неизменным. Мое исследование показало мне, что этого следует ожидать при работе с асинхронным кодом.

Большинство примеров, которые я прочитал, ограничивают область применения Toast для отображения ответа на экране. Пара изменяет действия внутри метода, но это идет вразрез с разделением уровней, которого я пытаюсь достичь, выполняя действия по представлению внутри уровня доступа к базе данных (и, возможно, также выполняю бизнес-логику, так как мое приложение становится более сложным).

Итак, как я могу получить объект внутри обратного вызова? (Например, String, содержащий ответ, или перечисление, указывающее результат операции). Если это невозможно или нежелательно, как я могу структурировать код, чтобы разделить проблемы?

Заранее благодарю за любые предложения, которые могли бы направить меня в правильном направлении.

...