Возвращение данных из onResponse Androi

Всем привет! У меня есть класс sendData для работы с сетью в котором реализован синглтон:

public static void initInstance()
{
    if (instance == null)
        instance = new SendData();
}


public static SendData getInstance()
{
    return instance;
}

В Main Activity я инициализирую его:

sendData = SendData.getInstance();

И использую для передачи параметров при загрузке:

private void loadItemsList()
{
    HashMap<String, Object> params = new HashMap();
    sendData.send(Constants.LOAD_ITEMS, params);
}

В классе SendData прописана отправка запроса на сервер:

public void send(final String apiName, HashMap<String, Object> params)
{
    JSONObject mainJsonObject = new JSONObject();
    JSONObject paramJsonObject = new JSONObject();
    try
    {
        mainJsonObject.put("name", apiName);

        for (Map.Entry<String, Object> entry: params.entrySet())
            paramJsonObject.put(entry.getKey(), entry.getValue().toString());

        mainJsonObject.put("param", paramJsonObject);
    }
    catch (JSONException e){e.printStackTrace();}

    final String jsonString = mainJsonObject.toString();

    StringRequest stringRequest = new StringRequest(Request.Method.POST, API_URL,
            new Response.Listener<String>()
            {
                @Override
                public void onResponse(String response)
                {
                    try
                    {
                        Log.d("RESPONCE_TAG", "onResponse: " + response);

                        JSONObject jsonObject = new JSONObject(response);
                        int status = jsonObject.getInt("status");

                        if (status == 200)
                        {
                           // разбор JSON
                        }
                    }
                    catch (JSONException e)
                    {
                        e.printStackTrace();
                        Log.d("ERROR_TAG", "onResponse: " + e.toString());
                    }
                }
            },
            new Response.ErrorListener()
            {
                @Override
                public void onErrorResponse(VolleyError error)
                {
                    Log.d("ERROR_TAG", "onErrorResponse: " + error.toString());
                }
            })
    {
        @Override
        public Map getHeaders() throws AuthFailureError
        {
            HashMap headers = new HashMap();
            headers.put("Content-Type", "application/json");
            headers.put("Authorization", "KEY");

            return headers;
        }

        @Override
        public byte[] getBody() throws AuthFailureError
        {
            try { return jsonString == null ? null : jsonString.getBytes("utf-8"); }
            catch (UnsupportedEncodingException ex) { return null; }
        }
    };

    RequestQueue requestQueue = Volley.newRequestQueue(App.get());
    requestQueue.add(stringRequest);
}

Каким образом я могу вернуть данные в Main Activity после успешного ответа от сервера? Например здесь:

if (status == 200)
{
    // разбор JSON
    // передача jsonObject в Main Activity
}

Ответы (1 шт):

Автор решения: Sergei Buvaka

Ну тут есть пару вариантов.

  • Это вернуть колбек в активити:

    class Activity extends AppCompatActivity{
    
        // ...
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            api.load.enqueue(new Callback<Post>() {
                @Override
                public void onResponse(@NonNull Call<Post> call, @NonNull Response<Post> response) {
                   // handle result - тут вы и получите ваш результат 
                }
    
                @Override
                public void onFailure(@NonNull Call<Post> call, @NonNull Throwable t) {
                    // handle error - здесь вы обработаете ошибку
                }
            });
        }
    }
    
  • Но само собой что писать такой код в активити плохая затея. Поэтому можно вынести его куда-нибудь в Presenter/ViewModel.

    class Presenter {
    
        Api api = Api.newInstance();
    
        // ...
    
        public void loadData() {
            api.load.enqueue(new Callback<Post>() {
                @Override
                public void onResponse(@NonNull Call<Post> call, @NonNull Response<Post> response) {
                   // handle result - тут вы и получите ваш результат и можете вызвать один из методов вашей View для его обработки
                   view.onSuccess(response.body());
                }
    
                @Override
                public void onFailure(@NonNull Call<Post> call, @NonNull Throwable t) {
                    // handle error - здесь вы обработаете ошибку. Так же вызываете иной метод в вашей View для обработки ошибки.
                    view.onError(t);
                }
            });
        }
    }
    
  • Вы можете выполнить операцию синхронно, что-то вроде такого:

    api.load. execute()
    

    тогда вы получите результат аналогично функции с возвращаемым значением. Но это крайне плохо т.к. вы заблокируете UI поток и интерфейс может "лагать", а второе вам будет сложнее корректно обрабатывать ошибки

UPD

Что такое onSuccess() и onError() это ваш собственный интерфейс для работы с View. Что-то вроде такого:

interface View {
    
    public void onSuccess(List<YourData> data);

    public void onError(Throwable th);
}

Этот интерфейс должна реализовать ваша Activity. А Presenter иметь ссылку на интерфейс.

Описывать тут принцип MVP я не могу, это займет оч много времени, но вы можете посмотреть хороший пример для начинающих и вот тут более продвинутый.

→ Ссылка