Асинхронный обратный вызов в потоке

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

Цель состоит в том, чтобы вызвать API-интерфейс внешней службы (с помощью Volley) и сохранить результат в базе данных (с помощью Room).

Я начал с макета результата API и сохранил его в базе данных. Следуя хорошей практике, я использовал для этого отдельный поток. Позже я добавил запрос API с помощью RequestQueue, и теперь у меня есть что-то вроде этого:

// HomeActivity.java
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    importData();
}

private void importData() {
    Thread importData = new Thread(new ImportData());
    importData.start();
    importData.join();
}

.

// ImportData.java
public class ImportData implements Runnable {

@Override
public void run() {

    String url = "http://api.com";

    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
            (Request.Method.GET, url, null, new Response.Listener<JSONObject>() {

                @Override
                public void onResponse(JSONObject response) {
                    String data = response.toString();

                    List<Data> toAdd = new ArrayList<>();
                    // ... formating data ...

                    App.get().getDB().dataDao().insertAll(toAdd);
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                }
            });

    App.INSTANCE.getRequestQueue().add(jsonObjectRequest);
}

Проблема в том, что после вызова в функции onResponse я снова в потоке пользовательского интерфейса, поэтому я не могу использовать операции с базой данных. Должен ли я создать там новую ветку? Если так, мне пришлось бы передать переменную ответа в этот поток, поэтому я не думаю, что это хорошая идея. Какие еще варианты и какой лучший? Это моя проблема.

Или вы получаете асинхронный результат внутри onResponse (без потока), или вы вызываете операцию синхронизации внутри своего потока, но второй способ имеет тот же эффект, что и выполнение только в одном потоке

Marcos Vasconcelos 31.07.2018 21:41
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
1
107
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Нет другого способа, кроме создания здесь нового потока, иначе вы должны иметь возможность получать сетевой результат в потоке, отличном от основного потока (Rx-java с модификацией может помочь вам там), или вы можете использовать RxVolley, если хотите чтобы следовать текущему коду, просто используйте AsyncTask, передайте данные в асинхронную задачу и сделайте транзакции базы данных в doInBackground ()

Ответ принят как подходящий

Кажется, это хороший кандидат для создания Volley индивидуальный запрос.

Вы можете создать класс, который расширяет Request и делать любые фоновые вещи, которые вы хотите (например, сохранение в вашу базу данных) в parseNetworkResponse, поскольку он вызывается из рабочего потока. Затем, когда запрос завершен, вы можете выполнять любые последующие действия потока пользовательского интерфейса в deliveryResponse, поскольку этот обратный вызов выполняется в основном потоке.

Другие вопросы по теме