Я реализую простое мобильное приложение с учетными записями пользователей. Кроме того, он должен быть структурирован в многоуровневой архитектуре, которая четко разделяет представление, логику и доступ к базе данных.
В настоящее время я могу отправлять и получать данные с сервера, используя библиотеку залпов. Однако эти данные доступны только внутри метода 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
, содержащий ответ, или перечисление, указывающее результат операции).
Если это невозможно или нежелательно, как я могу структурировать код, чтобы разделить проблемы?
Заранее благодарю за любые предложения, которые могли бы направить меня в правильном направлении.